From 1bedee8853272228e8ce34fb32201da533f06f33 Mon Sep 17 00:00:00 2001 From: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> Date: Tue, 26 Dec 2023 14:54:44 +0530 Subject: [PATCH 01/37] fix cancel download popup not shown Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> --- screens/Home/MyVcs/AddVcModalController.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/screens/Home/MyVcs/AddVcModalController.ts b/screens/Home/MyVcs/AddVcModalController.ts index cf3e770b16..49dbe93603 100644 --- a/screens/Home/MyVcs/AddVcModalController.ts +++ b/screens/Home/MyVcs/AddVcModalController.ts @@ -7,6 +7,7 @@ import { selectIsRequestingCredential, selectOtpError, selectIsAcceptingIdInput, + selectIsCancellingDownload, } from './AddVcModalMachine'; export function useAddVcModal({service}: AddVcModalProps) { @@ -17,6 +18,7 @@ export function useAddVcModal({service}: AddVcModalProps) { isAcceptingUinInput: useSelector(service, selectIsAcceptingIdInput), isAcceptingOtpInput: useSelector(service, selectIsAcceptingOtpInput), + isDownloadCancelled: useSelector(service, selectIsCancellingDownload), INPUT_OTP: (otp: string) => service.send(AddVcModalEvents.INPUT_OTP(otp)), From c3223f2f32bfa817833c54bc4a305fda9aa3bb95 Mon Sep 17 00:00:00 2001 From: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> Date: Tue, 26 Dec 2023 15:23:40 +0530 Subject: [PATCH 02/37] fix: show tuvali version Co-authored-by: vijay151096 <94220135+vijay151096@users.noreply.github.com> Signed-off-by: KiruthikaJeyashankar <81218987+KiruthikaJeyashankar@users.noreply.github.com> --- shared/GlobalVariables.ts | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/shared/GlobalVariables.ts b/shared/GlobalVariables.ts index 45d372e462..2063cd82dc 100644 --- a/shared/GlobalVariables.ts +++ b/shared/GlobalVariables.ts @@ -5,22 +5,16 @@ import {APP_ID_LENGTH} from './constants'; const dependencies = require('../package-lock.json').dependencies; function getTuvaliPackageDetails() { - let packageVersion, packageCommitId; - + let packageVersion; Object.keys(dependencies).forEach(dependencyName => { const dependencyData = dependencies[dependencyName]; - if (dependencyName == '@mosip/tuvali') { - packageVersion = dependencyData.from - ? dependencyData.from.split('#')[1] + packageVersion = dependencyData?.version + ? dependencyData.version : 'unknown'; - - if (packageVersion != 'unknown') { - packageCommitId = dependencyData.version.split('#')[1].substring(0, 7); - } } }); - return {packageVersion, packageCommitId}; + return {packageVersion}; } export class __AppId { private static value: string; @@ -36,16 +30,12 @@ export class __AppId { export class __TuvaliVersion { private static packageDetails = getTuvaliPackageDetails(); - public static getPackageCommitId(): string { - return __TuvaliVersion.packageDetails.packageCommitId; - } - public static getpackageVersion(): string { return __TuvaliVersion.packageDetails.packageVersion; } public static getValue(): string { - return this.getpackageVersion() + '-' + this.getPackageCommitId(); + return this.getpackageVersion(); } } export class __InjiVersion { From 633f42f65f07612f4ed628c650841a12c034e235 Mon Sep 17 00:00:00 2001 From: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> Date: Tue, 9 Jan 2024 12:26:22 +0530 Subject: [PATCH 03/37] downgrade tuvali version to 0.4.6 for qa testing (#1149) Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> --- .talismanrc | 4 ++-- ios/Podfile.lock | 18 +++++++++--------- package-lock.json | 14 +++++++------- package.json | 3 +-- shared/GlobalVariables.ts | 4 ++-- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/.talismanrc b/.talismanrc index 36656c59bb..c4d2b2f8d0 100644 --- a/.talismanrc +++ b/.talismanrc @@ -2,7 +2,7 @@ fileignoreconfig: - filename: package.json checksum: 984f91af6d696faf934f7e541801343e146aed1b58d7c950ba11ec02dbd60dda - filename: package-lock.json - checksum: baf08330efcaedd72275354d8e691f0004e0583d0f494a1e40b821fe7ec9046f + checksum: 2f2de69244aa1b6301c8fc68e9f4eb48d1c7f75c3d2d476a9f212ba17a21df51 - filename: lib/jsonld-signatures/suites/ed255192018/ed25519.ts checksum: 493b6e31144116cb612c24d98b97d8adcad5609c0a52c865a6847ced0a0ddc3a - filename: components/PasscodeVerify.tsx @@ -42,7 +42,7 @@ fileignoreconfig: - filename: screens/Issuers/IssuersScreen.tsx checksum: 9c53e3770dbefe26e0de67ee4b7d5cc9c52d9823cbb136a1a5104dcb0a101071 - filename: ios/Podfile.lock - checksum: 2487c4e11fb1bd95032cc4511435d9420fc0dfc62f3c015d177213fa089df7f2 + checksum: d637e9886e5cca824419c833a9dc524a667e22d6c5229e7c79356b4c6fb1d1ff - filename: screens/Home/IntroSlidersScreen.tsx checksum: 72ef913857448ef05763e52e32356faa2d1f3de8130a1c638d1897f44823031f - filename: shared/commonUtil.ts diff --git a/ios/Podfile.lock b/ios/Podfile.lock index f2a019ff3b..956b00d021 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -371,6 +371,10 @@ PODS: - React-Core - react-native-spinkit (1.4.1): - React + - react-native-tuvali (0.4.6): + - CrcSwift (~> 0.0.3) + - GzipSwift + - React-Core - React-perflogger (0.71.8) - React-RCTActionSheet (0.71.8): - React-Core/RCTActionSheetHeaders (= 0.71.8) @@ -492,10 +496,6 @@ PODS: - TensorFlowLiteObjC/Core (= 2.12.0) - TensorFlowLiteObjC/Core (2.12.0): - TensorFlowLiteC (= 2.12.0) - - tuvali (0.4.9): - - CrcSwift (~> 0.0.3) - - GzipSwift - - React-Core - Yoga (1.14.0) - ZXingObjC/Core (3.6.5) - ZXingObjC/OneD (3.6.5): @@ -560,6 +560,7 @@ DEPENDENCIES: - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-secure-key-store (from `../node_modules/react-native-secure-key-store`) - react-native-spinkit (from `../node_modules/react-native-spinkit`) + - "react-native-tuvali (from `../node_modules/@mosip/tuvali`)" - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) @@ -587,7 +588,6 @@ DEPENDENCIES: - RNSecureRandom (from `../node_modules/react-native-securerandom`) - RNSVG (from `../node_modules/react-native-svg`) - "secure-keystore (from `../node_modules/@mosip/secure-keystore`)" - - "tuvali (from `../node_modules/@mosip/tuvali`)" - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: @@ -716,6 +716,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-secure-key-store" react-native-spinkit: :path: "../node_modules/react-native-spinkit" + react-native-tuvali: + :path: "../node_modules/@mosip/tuvali" React-perflogger: :path: "../node_modules/react-native/ReactCommon/reactperflogger" React-RCTActionSheet: @@ -770,8 +772,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-svg" secure-keystore: :path: "../node_modules/@mosip/secure-keystore" - tuvali: - :path: "../node_modules/@mosip/tuvali" Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" @@ -780,7 +780,7 @@ SPEC CHECKSUMS: ASN1Decoder: 6110fdeacfdb41559b1481457a1645be716610aa biometric-sdk-react-native: d2a3a1279013cc4a7514a1b43fe557eb76e4e4c1 BiometricSdk: 303e7329404ea4d922dc14108449d10d21574f77 - boost: 64032b9e9b938fda23325e68a3771f0fabf414dc + boost: 57d2868c099736d80fcd648bf211b4431e51a558 BVLinearGradient: 916632041121a658c704df89d99f04acb038de0f CatCrypto: a477899b6be4954e75be4897e732da098cc0a5a8 CrcSwift: f85dea6b41dddb5f98bb3743fd777ce58b77bc2e @@ -841,6 +841,7 @@ SPEC CHECKSUMS: react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc react-native-secure-key-store: 910e6df6bc33cb790aba6ee24bc7818df1fe5898 react-native-spinkit: da294fd828216ad211fe36a5c14c1e09f09e62db + react-native-tuvali: bd369208d58ff9e1528c2a76dce126f60d7fd35d React-perflogger: d21f182895de9d1b077f8a3cd00011095c8c9100 React-RCTActionSheet: 0151f83ef92d2a7139bba7dfdbc8066632a6d47b React-RCTAnimation: 5ec9c0705bb2297549c120fe6473aa3e4a01e215 @@ -870,7 +871,6 @@ SPEC CHECKSUMS: secure-keystore: 21c03ba81520aefa99621383770ce00b3e306c72 TensorFlowLiteC: 20785a69299185a379ba9852b6625f00afd7984a TensorFlowLiteObjC: 9a46a29a76661c513172cfffd3bf712b11ef25c3 - tuvali: 9c3aad61844f6fcbd48ec7967cd6805418c3f8da Yoga: 065f0b74dba4832d6e328238de46eb72c5de9556 ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb diff --git a/package-lock.json b/package-lock.json index 3fd8087ab5..dba7750731 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@expo/metro-config": "~0.10.0", "@iriscan/biometric-sdk-react-native": "^0.2.6", "@mosip/secure-keystore": "^0.1.5", - "@mosip/tuvali": "^0.4.9", + "@mosip/tuvali": "github:mosip/tuvali#0.4.6", "@react-native-clipboard/clipboard": "^1.10.0", "@react-native-community/netinfo": "9.3.7", "@react-native-picker/picker": "2.4.8", @@ -6186,9 +6186,10 @@ } }, "node_modules/@mosip/tuvali": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/@mosip/tuvali/-/tuvali-0.4.9.tgz", - "integrity": "sha512-WnpnM9EAJKEBdZ71DPSeh2va5LDy01iWFI3Ngtc4KfJ4XHWyQbRQA/1T4QPDgofMTP8wy9wehD7w4m8K8YJdhw==", + "name": "react-native-tuvali", + "version": "0.4.6", + "resolved": "git+ssh://git@github.com/mosip/tuvali.git#1dc8ef8f0a05a5962e02fe0fbbaa9055f775b11f", + "license": "MIT", "peerDependencies": { "react": "*", "react-native": "*" @@ -33561,9 +33562,8 @@ "requires": {} }, "@mosip/tuvali": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/@mosip/tuvali/-/tuvali-0.4.9.tgz", - "integrity": "sha512-WnpnM9EAJKEBdZ71DPSeh2va5LDy01iWFI3Ngtc4KfJ4XHWyQbRQA/1T4QPDgofMTP8wy9wehD7w4m8K8YJdhw==", + "version": "git+ssh://git@github.com/mosip/tuvali.git#1dc8ef8f0a05a5962e02fe0fbbaa9055f775b11f", + "from": "@mosip/tuvali@github:mosip/tuvali#0.4.6", "requires": {} }, "@nicolo-ribaudo/eslint-scope-5-internals": { diff --git a/package.json b/package.json index e300b9f12a..374e9e413c 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "@expo/metro-config": "~0.10.0", "@iriscan/biometric-sdk-react-native": "^0.2.6", "@mosip/secure-keystore": "^0.1.5", - "@mosip/tuvali": "^0.4.9", + "@mosip/tuvali": "github:mosip/tuvali#0.4.6", "@react-native-clipboard/clipboard": "^1.10.0", "@react-native-community/netinfo": "9.3.7", "@react-native-picker/picker": "2.4.8", @@ -28,7 +28,6 @@ "@react-navigation/native": "^6.0.8", "@react-navigation/native-stack": "^6.1.0", "@xstate/react": "^3.0.1", - "@iriscan/biometric-sdk-react-native": "^0.2.6", "base64url-universal": "^1.1.0", "buffer": "^6.0.3", "date-fns": "^2.26.0", diff --git a/shared/GlobalVariables.ts b/shared/GlobalVariables.ts index 2063cd82dc..3524136c75 100644 --- a/shared/GlobalVariables.ts +++ b/shared/GlobalVariables.ts @@ -9,8 +9,8 @@ function getTuvaliPackageDetails() { Object.keys(dependencies).forEach(dependencyName => { const dependencyData = dependencies[dependencyName]; if (dependencyName == '@mosip/tuvali') { - packageVersion = dependencyData?.version - ? dependencyData.version + packageVersion = dependencyData.from + ? dependencyData.from.split('#')[1] : 'unknown'; } }); From 710b8e5cccd13b0c2cbad94dd58b6bc8cdf577e7 Mon Sep 17 00:00:00 2001 From: Swati Goel Date: Wed, 17 Jan 2024 12:40:20 +0530 Subject: [PATCH 04/37] Revert "downgrade tuvali version to 0.4.6 for qa testing (#1149)" This reverts commit 633f42f65f07612f4ed628c650841a12c034e235. Signed-off-by: Swati Goel --- .talismanrc | 4 ++-- ios/Podfile.lock | 18 +++++++++--------- package-lock.json | 14 +++++++------- package.json | 3 ++- shared/GlobalVariables.ts | 4 ++-- 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.talismanrc b/.talismanrc index c4d2b2f8d0..36656c59bb 100644 --- a/.talismanrc +++ b/.talismanrc @@ -2,7 +2,7 @@ fileignoreconfig: - filename: package.json checksum: 984f91af6d696faf934f7e541801343e146aed1b58d7c950ba11ec02dbd60dda - filename: package-lock.json - checksum: 2f2de69244aa1b6301c8fc68e9f4eb48d1c7f75c3d2d476a9f212ba17a21df51 + checksum: baf08330efcaedd72275354d8e691f0004e0583d0f494a1e40b821fe7ec9046f - filename: lib/jsonld-signatures/suites/ed255192018/ed25519.ts checksum: 493b6e31144116cb612c24d98b97d8adcad5609c0a52c865a6847ced0a0ddc3a - filename: components/PasscodeVerify.tsx @@ -42,7 +42,7 @@ fileignoreconfig: - filename: screens/Issuers/IssuersScreen.tsx checksum: 9c53e3770dbefe26e0de67ee4b7d5cc9c52d9823cbb136a1a5104dcb0a101071 - filename: ios/Podfile.lock - checksum: d637e9886e5cca824419c833a9dc524a667e22d6c5229e7c79356b4c6fb1d1ff + checksum: 2487c4e11fb1bd95032cc4511435d9420fc0dfc62f3c015d177213fa089df7f2 - filename: screens/Home/IntroSlidersScreen.tsx checksum: 72ef913857448ef05763e52e32356faa2d1f3de8130a1c638d1897f44823031f - filename: shared/commonUtil.ts diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 956b00d021..f2a019ff3b 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -371,10 +371,6 @@ PODS: - React-Core - react-native-spinkit (1.4.1): - React - - react-native-tuvali (0.4.6): - - CrcSwift (~> 0.0.3) - - GzipSwift - - React-Core - React-perflogger (0.71.8) - React-RCTActionSheet (0.71.8): - React-Core/RCTActionSheetHeaders (= 0.71.8) @@ -496,6 +492,10 @@ PODS: - TensorFlowLiteObjC/Core (= 2.12.0) - TensorFlowLiteObjC/Core (2.12.0): - TensorFlowLiteC (= 2.12.0) + - tuvali (0.4.9): + - CrcSwift (~> 0.0.3) + - GzipSwift + - React-Core - Yoga (1.14.0) - ZXingObjC/Core (3.6.5) - ZXingObjC/OneD (3.6.5): @@ -560,7 +560,6 @@ DEPENDENCIES: - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-secure-key-store (from `../node_modules/react-native-secure-key-store`) - react-native-spinkit (from `../node_modules/react-native-spinkit`) - - "react-native-tuvali (from `../node_modules/@mosip/tuvali`)" - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) @@ -588,6 +587,7 @@ DEPENDENCIES: - RNSecureRandom (from `../node_modules/react-native-securerandom`) - RNSVG (from `../node_modules/react-native-svg`) - "secure-keystore (from `../node_modules/@mosip/secure-keystore`)" + - "tuvali (from `../node_modules/@mosip/tuvali`)" - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: @@ -716,8 +716,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-secure-key-store" react-native-spinkit: :path: "../node_modules/react-native-spinkit" - react-native-tuvali: - :path: "../node_modules/@mosip/tuvali" React-perflogger: :path: "../node_modules/react-native/ReactCommon/reactperflogger" React-RCTActionSheet: @@ -772,6 +770,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-svg" secure-keystore: :path: "../node_modules/@mosip/secure-keystore" + tuvali: + :path: "../node_modules/@mosip/tuvali" Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" @@ -780,7 +780,7 @@ SPEC CHECKSUMS: ASN1Decoder: 6110fdeacfdb41559b1481457a1645be716610aa biometric-sdk-react-native: d2a3a1279013cc4a7514a1b43fe557eb76e4e4c1 BiometricSdk: 303e7329404ea4d922dc14108449d10d21574f77 - boost: 57d2868c099736d80fcd648bf211b4431e51a558 + boost: 64032b9e9b938fda23325e68a3771f0fabf414dc BVLinearGradient: 916632041121a658c704df89d99f04acb038de0f CatCrypto: a477899b6be4954e75be4897e732da098cc0a5a8 CrcSwift: f85dea6b41dddb5f98bb3743fd777ce58b77bc2e @@ -841,7 +841,6 @@ SPEC CHECKSUMS: react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc react-native-secure-key-store: 910e6df6bc33cb790aba6ee24bc7818df1fe5898 react-native-spinkit: da294fd828216ad211fe36a5c14c1e09f09e62db - react-native-tuvali: bd369208d58ff9e1528c2a76dce126f60d7fd35d React-perflogger: d21f182895de9d1b077f8a3cd00011095c8c9100 React-RCTActionSheet: 0151f83ef92d2a7139bba7dfdbc8066632a6d47b React-RCTAnimation: 5ec9c0705bb2297549c120fe6473aa3e4a01e215 @@ -871,6 +870,7 @@ SPEC CHECKSUMS: secure-keystore: 21c03ba81520aefa99621383770ce00b3e306c72 TensorFlowLiteC: 20785a69299185a379ba9852b6625f00afd7984a TensorFlowLiteObjC: 9a46a29a76661c513172cfffd3bf712b11ef25c3 + tuvali: 9c3aad61844f6fcbd48ec7967cd6805418c3f8da Yoga: 065f0b74dba4832d6e328238de46eb72c5de9556 ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb diff --git a/package-lock.json b/package-lock.json index dba7750731..3fd8087ab5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@expo/metro-config": "~0.10.0", "@iriscan/biometric-sdk-react-native": "^0.2.6", "@mosip/secure-keystore": "^0.1.5", - "@mosip/tuvali": "github:mosip/tuvali#0.4.6", + "@mosip/tuvali": "^0.4.9", "@react-native-clipboard/clipboard": "^1.10.0", "@react-native-community/netinfo": "9.3.7", "@react-native-picker/picker": "2.4.8", @@ -6186,10 +6186,9 @@ } }, "node_modules/@mosip/tuvali": { - "name": "react-native-tuvali", - "version": "0.4.6", - "resolved": "git+ssh://git@github.com/mosip/tuvali.git#1dc8ef8f0a05a5962e02fe0fbbaa9055f775b11f", - "license": "MIT", + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@mosip/tuvali/-/tuvali-0.4.9.tgz", + "integrity": "sha512-WnpnM9EAJKEBdZ71DPSeh2va5LDy01iWFI3Ngtc4KfJ4XHWyQbRQA/1T4QPDgofMTP8wy9wehD7w4m8K8YJdhw==", "peerDependencies": { "react": "*", "react-native": "*" @@ -33562,8 +33561,9 @@ "requires": {} }, "@mosip/tuvali": { - "version": "git+ssh://git@github.com/mosip/tuvali.git#1dc8ef8f0a05a5962e02fe0fbbaa9055f775b11f", - "from": "@mosip/tuvali@github:mosip/tuvali#0.4.6", + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@mosip/tuvali/-/tuvali-0.4.9.tgz", + "integrity": "sha512-WnpnM9EAJKEBdZ71DPSeh2va5LDy01iWFI3Ngtc4KfJ4XHWyQbRQA/1T4QPDgofMTP8wy9wehD7w4m8K8YJdhw==", "requires": {} }, "@nicolo-ribaudo/eslint-scope-5-internals": { diff --git a/package.json b/package.json index 374e9e413c..e300b9f12a 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "@expo/metro-config": "~0.10.0", "@iriscan/biometric-sdk-react-native": "^0.2.6", "@mosip/secure-keystore": "^0.1.5", - "@mosip/tuvali": "github:mosip/tuvali#0.4.6", + "@mosip/tuvali": "^0.4.9", "@react-native-clipboard/clipboard": "^1.10.0", "@react-native-community/netinfo": "9.3.7", "@react-native-picker/picker": "2.4.8", @@ -28,6 +28,7 @@ "@react-navigation/native": "^6.0.8", "@react-navigation/native-stack": "^6.1.0", "@xstate/react": "^3.0.1", + "@iriscan/biometric-sdk-react-native": "^0.2.6", "base64url-universal": "^1.1.0", "buffer": "^6.0.3", "date-fns": "^2.26.0", diff --git a/shared/GlobalVariables.ts b/shared/GlobalVariables.ts index 3524136c75..2063cd82dc 100644 --- a/shared/GlobalVariables.ts +++ b/shared/GlobalVariables.ts @@ -9,8 +9,8 @@ function getTuvaliPackageDetails() { Object.keys(dependencies).forEach(dependencyName => { const dependencyData = dependencies[dependencyName]; if (dependencyName == '@mosip/tuvali') { - packageVersion = dependencyData.from - ? dependencyData.from.split('#')[1] + packageVersion = dependencyData?.version + ? dependencyData.version : 'unknown'; } }); From 336961bc4523b0bd899dc2b157088dc10a9429f4 Mon Sep 17 00:00:00 2001 From: vijay151096 <94220135+vijay151096@users.noreply.github.com> Date: Thu, 25 Jan 2024 10:04:37 +0530 Subject: [PATCH 05/37] Resetting the Data_Backup Toggle (#1202) --- .env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env b/.env index 2957cb5b69..f052f29bcc 100644 --- a/.env +++ b/.env @@ -14,7 +14,7 @@ APPLICATION_THEME=orange #environment can be changed if it is toggled CREDENTIAL_REGISTRY_EDIT=true #DataBackup can enable if it is toggled -DATA_BACKUP=true +DATA_BACKUP=false DEBUG_MODE=false #supported languages( en, fil, ar, hi, kn, ta) From 2e8b8b01a99709332173eac5d3c6a10ff2277def Mon Sep 17 00:00:00 2001 From: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:26:30 +0530 Subject: [PATCH 06/37] [INJI-766] set backupAndRestore env variable to true and remove full stop in the kan langugage in one of the help page question Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> --- .env | 2 +- .talismanrc | 2 +- locales/kan.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.env b/.env index c044615923..d7fae89366 100644 --- a/.env +++ b/.env @@ -14,7 +14,7 @@ APPLICATION_THEME=orange #environment can be changed if it is toggled CREDENTIAL_REGISTRY_EDIT=true #DataBackup can enable if it is toggled -BACKUP_AND_RESTORE=false +BACKUP_AND_RESTORE=true DEBUG_MODE=false #supported languages( en, fil, ar, hi, kn, ta) diff --git a/.talismanrc b/.talismanrc index 3ba7e2bb81..78ba034268 100644 --- a/.talismanrc +++ b/.talismanrc @@ -128,7 +128,7 @@ fileignoreconfig: - filename: machines/settings.typegen.ts checksum: e4ae05822f1b1c23f3f70d03dd46fd8f29ba6b52d40f2f24c121f536fbb5f2c4 - filename: .env - checksum: ae9586991aff83b0cbefb01fccfda729c7cb0fa3aa34696e88a16aa7c5c34bb5 + checksum: 399e4dadae9dbd22612f48c8583fd64d6f07e9e1fcb0b57a1a8874b056da4b6c - filename: .github/workflows/ui-automation.yml checksum: 0b26a5dcb7524ba15d6aaeaf04f2ef94be9d25ef702d9072d6628bcd58e50f36 - filename: injitest/src/test/java/androidTestCases/PinVcTest.java diff --git a/locales/kan.json b/locales/kan.json index 7158f3d601..77ef353772 100644 --- a/locales/kan.json +++ b/locales/kan.json @@ -208,7 +208,7 @@ "whatIsAnId?":"ಐಡಿ ಎಂದರೇನು?", "detail-10":"ಐಡಿ ಎನ್ನುವುದು ವ್ಯಕ್ತಿಯ ಗುರುತನ್ನು ಸಾಬೀತುಪಡಿಸುವ ಯಾವುದೇ ದಾಖಲೆಯಾಗಿದೆ. MOSIP ನ ಸಂದರ್ಭದಲ್ಲಿ, ಗುರುತಿಸುವಿಕೆಗಳು ವ್ಯವಸ್ಥೆಯಲ್ಲಿನ ಗುರುತುಗಳಿಗಾಗಿ ಆಲ್ಫಾನ್ಯೂಮರಿಕ್ ಡಿಜಿಟಲ್ ಹ್ಯಾಂಡಲ್‌ಗಳಾಗಿವೆ. ವ್ಯಕ್ತಿಯ ಗುರುತನ್ನು ವ್ಯಕ್ತಿಯನ್ನು ಅನನ್ಯವಾಗಿ ಗುರುತಿಸಬಲ್ಲ ಜೀವನಚರಿತ್ರೆಯ ಮತ್ತು ಬಯೋಮೆಟ್ರಿಕ್ ಗುಣಲಕ್ಷಣಗಳ ಸಂಗ್ರಹವಾಗಿ ಪ್ರತಿನಿಧಿಸಲಾಗುತ್ತದೆ, ಗುರುತನ್ನು ಗುರುತಿಸುವಿಕೆಗಳನ್ನು ಬಳಸುವುದನ್ನು ಉಲ್ಲೇಖಿಸಲಾಗುತ್ತದೆ.", "whatAreTheDifferentTypesOfId?": "ಐಡಿ ಯ ವಿವಿಧ ಪ್ರಕಾರಗಳು ಯಾವುವು?", - "detail-11":"MOSIP ನ ಸಂದರ್ಭದಲ್ಲಿ, ವಿಭಿನ್ನ ಐಡಿ ಗಳು UIN, VID ಮತ್ತು AID. ಅವರ ಬಗ್ಗೆ ಇನ್ನಷ್ಟು ಓದಿ.", + "detail-11":"MOSIP ನ ಸಂದರ್ಭದಲ್ಲಿ, ವಿಭಿನ್ನ ಐಡಿ ಗಳು UIN, VID ಮತ್ತು AID. ಅವರ ಬಗ್ಗೆ ಇನ್ನಷ್ಟು ಓದಿ", "whereCanIFindTheseIds?":"ನಾನು ಈ ಐಡಿಗಳನ್ನು ಎಲ್ಲಿ ಹುಡುಕಬಹುದು?", "detail-12a": "ನೋಂದಣಿ (ನೋಂದಣಿ) ಪ್ರಕ್ರಿಯೆಯ ಭಾಗವಾಗಿ, ಜನಸಂಖ್ಯಾ ಮಾಹಿತಿ ಮತ್ತು ನಿವಾಸಿಗಳ ಬಯೋಮೆಟ್ರಿಕ್ಸ್ ಅನ್ನು ಯಶಸ್ವಿಯಾಗಿ ನೋಂದಾಯಿಸಿದ ನಂತರ, ನೋಂದಣಿ ಐಡಿ (AID) ಅನ್ನು ನಿವಾಸಿಗೆ ಹಂಚಲಾಗುತ್ತದೆ. ಸೆರೆಹಿಡಿಯಲಾದ ವಿವರಗಳನ್ನು ಒಳಗೊಂಡಿರುವ ಸ್ವೀಕೃತಿ ಚೀಟಿ ಮತ್ತು AID ಅನ್ನು ನೋಂದಣಿಯ ಪುರಾವೆಯಾಗಿ ನಿವಾಸಿಗೆ ನೀಡಲಾಗುತ್ತದೆ (ಮುದ್ರಿತ).", "detail-12b": "ಯಶಸ್ವಿ ಪ್ರಕ್ರಿಯೆಯ ನಂತರ, ನಿವಾಸಿಗೆ ವಿಶಿಷ್ಟ ಗುರುತಿನ ಸಂಖ್ಯೆ (UIN) ಅನ್ನು ಹಂಚಲಾಗುತ್ತದೆ ಮತ್ತು ನೋಂದಾಯಿತ ಫೋನ್ ಸಂಖ್ಯೆ ಮತ್ತು/ಅಥವಾ ಇಮೇಲ್‌ನಲ್ಲಿ ನಿವಾಸಿಗೆ ಅಧಿಸೂಚನೆಯನ್ನು ಕಳುಹಿಸಲಾಗುತ್ತದೆ.", From 01c8c8abeba840dd74da5d826f43b3222ba77287 Mon Sep 17 00:00:00 2001 From: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> Date: Sun, 4 Feb 2024 14:09:47 +0530 Subject: [PATCH 07/37] [INJI-766] remove backupAndRestore variable from env file Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> --- .env | 3 +-- .talismanrc | 2 +- screens/Settings/SettingScreen.tsx | 9 ++------- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.env b/.env index d7fae89366..5feeba55d2 100644 --- a/.env +++ b/.env @@ -13,8 +13,7 @@ APPLICATION_THEME=orange #environment can be changed if it is toggled CREDENTIAL_REGISTRY_EDIT=true -#DataBackup can enable if it is toggled -BACKUP_AND_RESTORE=true + DEBUG_MODE=false #supported languages( en, fil, ar, hi, kn, ta) diff --git a/.talismanrc b/.talismanrc index 78ba034268..02ec963803 100644 --- a/.talismanrc +++ b/.talismanrc @@ -128,7 +128,7 @@ fileignoreconfig: - filename: machines/settings.typegen.ts checksum: e4ae05822f1b1c23f3f70d03dd46fd8f29ba6b52d40f2f24c121f536fbb5f2c4 - filename: .env - checksum: 399e4dadae9dbd22612f48c8583fd64d6f07e9e1fcb0b57a1a8874b056da4b6c + checksum: 387e1fbafb92f58b152b751ec97e8e0e31a699c43e273c61bdedb67f8ee7e453 - filename: .github/workflows/ui-automation.yml checksum: 0b26a5dcb7524ba15d6aaeaf04f2ef94be9d25ef702d9072d6628bcd58e50f36 - filename: injitest/src/test/java/androidTestCases/PinVcTest.java diff --git a/screens/Settings/SettingScreen.tsx b/screens/Settings/SettingScreen.tsx index 8f8ce762dd..413a886c7b 100644 --- a/screens/Settings/SettingScreen.tsx +++ b/screens/Settings/SettingScreen.tsx @@ -10,10 +10,7 @@ import {useTranslation} from 'react-i18next'; import {LanguageSelector} from '../../components/LanguageSelector'; import {ScrollView} from 'react-native-gesture-handler'; import {Modal} from '../../components/ui/Modal'; -import { - CREDENTIAL_REGISTRY_EDIT, - BACKUP_AND_RESTORE, -} from 'react-native-dotenv'; +import {CREDENTIAL_REGISTRY_EDIT} from 'react-native-dotenv'; import {AboutInji} from './AboutInji'; import {EditableListItem} from '../../components/EditableListItem'; import {RequestRouteProps, RootRouteProps} from '../../routes'; @@ -166,9 +163,7 @@ export const SettingScreen: React.FC< - {BACKUP_AND_RESTORE === 'true' && isAndroid() && ( - - )} + {isAndroid() && } {CREDENTIAL_REGISTRY_EDIT === 'true' && ( Date: Mon, 12 Feb 2024 10:57:14 +0530 Subject: [PATCH 08/37] Revert "Merge pull request #1227 from tw-mosip/internal-release-01-02-2024" (#1242) This reverts commit 6de62fccb67f7b1da4219ea79edeba6dc56aeb10, reversing changes made to f63445fc0821311bb005880ab4c5ed8d1179a630. Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com> --- .env | 3 ++- .talismanrc | 2 +- screens/Settings/SettingScreen.tsx | 9 +++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.env b/.env index 5feeba55d2..d7fae89366 100644 --- a/.env +++ b/.env @@ -13,7 +13,8 @@ APPLICATION_THEME=orange #environment can be changed if it is toggled CREDENTIAL_REGISTRY_EDIT=true - +#DataBackup can enable if it is toggled +BACKUP_AND_RESTORE=true DEBUG_MODE=false #supported languages( en, fil, ar, hi, kn, ta) diff --git a/.talismanrc b/.talismanrc index 02ec963803..78ba034268 100644 --- a/.talismanrc +++ b/.talismanrc @@ -128,7 +128,7 @@ fileignoreconfig: - filename: machines/settings.typegen.ts checksum: e4ae05822f1b1c23f3f70d03dd46fd8f29ba6b52d40f2f24c121f536fbb5f2c4 - filename: .env - checksum: 387e1fbafb92f58b152b751ec97e8e0e31a699c43e273c61bdedb67f8ee7e453 + checksum: 399e4dadae9dbd22612f48c8583fd64d6f07e9e1fcb0b57a1a8874b056da4b6c - filename: .github/workflows/ui-automation.yml checksum: 0b26a5dcb7524ba15d6aaeaf04f2ef94be9d25ef702d9072d6628bcd58e50f36 - filename: injitest/src/test/java/androidTestCases/PinVcTest.java diff --git a/screens/Settings/SettingScreen.tsx b/screens/Settings/SettingScreen.tsx index 413a886c7b..8f8ce762dd 100644 --- a/screens/Settings/SettingScreen.tsx +++ b/screens/Settings/SettingScreen.tsx @@ -10,7 +10,10 @@ import {useTranslation} from 'react-i18next'; import {LanguageSelector} from '../../components/LanguageSelector'; import {ScrollView} from 'react-native-gesture-handler'; import {Modal} from '../../components/ui/Modal'; -import {CREDENTIAL_REGISTRY_EDIT} from 'react-native-dotenv'; +import { + CREDENTIAL_REGISTRY_EDIT, + BACKUP_AND_RESTORE, +} from 'react-native-dotenv'; import {AboutInji} from './AboutInji'; import {EditableListItem} from '../../components/EditableListItem'; import {RequestRouteProps, RootRouteProps} from '../../routes'; @@ -163,7 +166,9 @@ export const SettingScreen: React.FC< - {isAndroid() && } + {BACKUP_AND_RESTORE === 'true' && isAndroid() && ( + + )} {CREDENTIAL_REGISTRY_EDIT === 'true' && ( Date: Mon, 12 Feb 2024 12:23:09 +0530 Subject: [PATCH 09/37] [Internal-Release-20+] : Sunbird Changes (#1243) * [INJIMOB-683]: add testid for missed vc field (#1226) * [INJIMOB-683]: add testid for missed vc field Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> * [INJIMOB-683]: add testidprops for missed vc field Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> * [INJIMOB-683]: add testidprops for missed vc field Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> --------- Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> * [INJIMOB-770]: parse date received in the vc's (#1225) * [INJIMOB-770]: parse date received in the vc's Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> * [INJIMOB-770]: parse date received in the vc's Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> --------- Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> * downgrade cocoapods version (#1231) Signed-off-by: adityankannan-tw Co-authored-by: adityankannan-tw * Use latest cocoapods version (#1236) * downgrade cocoapods version Signed-off-by: adityankannan-tw * use latest cocoapods version Signed-off-by: adityankannan-tw --------- Signed-off-by: adityankannan-tw Signed-off-by: adityankannan-tw <109274996+adityankannan-tw@users.noreply.github.com> Co-authored-by: adityankannan-tw --------- Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> Signed-off-by: adityankannan-tw Signed-off-by: adityankannan-tw <109274996+adityankannan-tw@users.noreply.github.com> Co-authored-by: adityankannan-tw <109274996+adityankannan-tw@users.noreply.github.com> Co-authored-by: adityankannan-tw --- components/ProfileIcon.tsx | 17 +++++++++++++---- components/VC/common/VCItemField.tsx | 3 ++- components/VC/common/VCUtils.tsx | 25 ++++++------------------- ios/Podfile | 2 +- ios/Podfile.lock | 4 ++-- 5 files changed, 24 insertions(+), 27 deletions(-) diff --git a/components/ProfileIcon.tsx b/components/ProfileIcon.tsx index 975ce4519a..c1b0c30405 100644 --- a/components/ProfileIcon.tsx +++ b/components/ProfileIcon.tsx @@ -3,20 +3,29 @@ import {View} from 'react-native'; import React from 'react'; import {Icon} from 'react-native-elements'; import {SvgImage} from './ui/svg'; +import testIDProps from '../shared/commonUtil'; export const ProfileIcon: React.FC = props => { return ( - <> - + + {props?.isPinned && SvgImage.pinIcon()} - + - + ); }; diff --git a/components/VC/common/VCItemField.tsx b/components/VC/common/VCItemField.tsx index 6790e9f31f..3480829018 100644 --- a/components/VC/common/VCItemField.tsx +++ b/components/VC/common/VCItemField.tsx @@ -41,7 +41,8 @@ export const VCItemField = ({ {Array.isArray(fieldValue) ? ( fieldValue.map(field => ( {field} diff --git a/components/VC/common/VCUtils.tsx b/components/VC/common/VCUtils.tsx index 74e4cb5cea..c894ae7d90 100644 --- a/components/VC/common/VCUtils.tsx +++ b/components/VC/common/VCUtils.tsx @@ -6,7 +6,6 @@ import i18n, {getLocalizedField} from '../../../i18n'; import {Row} from '../../ui'; import {VCItemField} from './VCItemField'; import React from 'react'; -import {format, parse} from 'date-fns'; import {logoType} from '../../../machines/issuersMachine'; import {Image} from 'react-native'; import {Theme} from '../../ui/styleUtils'; @@ -41,17 +40,17 @@ export const getFieldValue = ( wellknown: any, props: any, ) => { + const date = new Date( + getLocalizedField(verifiableCredential?.credentialSubject[field]), + ).toString(); + if (date !== 'Invalid Date') { + return formattedDateTime(date); + } switch (field) { case 'status': return ; case 'idType': return getIDType(verifiableCredential); - case 'dateOfBirth': - return formattedDateOfBirth(verifiableCredential); - case 'expiresOn': - return formattedDateTime( - verifiableCredential?.credentialSubject.expiresOn, - ); case 'credentialRegistry': return props?.vc?.credentialRegistry; case 'address': @@ -125,17 +124,6 @@ function getFullAddress(credential: CredentialSubject) { .join(', '); } -function formattedDateOfBirth(verifiableCredential: any) { - const dateOfBirth = verifiableCredential?.credentialSubject.dateOfBirth; - if (dateOfBirth) { - const formatString = - dateOfBirth.split('/').length === 1 ? 'yyyy' : 'yyyy/MM/dd'; - const parsedDate = parse(dateOfBirth, formatString, new Date()); - return format(parsedDate, 'MM/dd/yyyy'); - } - return dateOfBirth; -} - function formattedDateTime(timeStamp: any) { if (timeStamp) { return new Date(timeStamp).toLocaleDateString(); @@ -168,7 +156,6 @@ export const fieldItemIterator = ( key={field} style={{flexDirection: 'row', flex: 1}} align="space-between" - let margin="0 8 5 0"> false prepare_react_native_project! diff --git a/ios/Podfile.lock b/ios/Podfile.lock index ed454a1394..8247173305 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -936,6 +936,6 @@ SPEC CHECKSUMS: Yoga: 065f0b74dba4832d6e328238de46eb72c5de9556 ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb -PODFILE CHECKSUM: 01f58b130fa221dabb14b2d82d981ef24dcaba53 +PODFILE CHECKSUM: 90dfa5dbb6ca0103a4e49014140523aff5458f68 -COCOAPODS: 1.14.2 +COCOAPODS: 1.15.2 From 20e23d0737dc0095d14118101540b918ba138478 Mon Sep 17 00:00:00 2001 From: Vijay <94220135+vijay151096@users.noreply.github.com> Date: Tue, 13 Feb 2024 19:03:43 +0530 Subject: [PATCH 10/37] [INJIMOB-760]: update mosip Logo Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> --- assets/Mosip_Logo1.svg | 211 +++++++++++++++++++++++++---------------- 1 file changed, 131 insertions(+), 80 deletions(-) diff --git a/assets/Mosip_Logo1.svg b/assets/Mosip_Logo1.svg index a87e015c57..4176bb94f6 100644 --- a/assets/Mosip_Logo1.svg +++ b/assets/Mosip_Logo1.svg @@ -1,97 +1,148 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -48,12 +50,9 @@ export const AccountSelectionConfirmation: React.FC< crossAlign="center" style={{paddingHorizontal: 120, paddingTop: 50}}> - {SvgImage.GoogleDriveIcon(45, 45)} - - {t('googleDriveTitle')} - + {isAndroid() + ? SvgImage.GoogleDriveIcon(207, 45) + : SvgImage.ICloudIcon(210, 45)} diff --git a/screens/backupAndRestore/BackupAndRestoreScreen.tsx b/screens/backupAndRestore/BackupAndRestoreScreen.tsx index 01c257c597..f12e22ec43 100644 --- a/screens/backupAndRestore/BackupAndRestoreScreen.tsx +++ b/screens/backupAndRestore/BackupAndRestoreScreen.tsx @@ -9,13 +9,14 @@ import {Modal} from '../../components/ui/Modal'; import {Timestamp} from '../../components/ui/Timestamp'; import {Theme} from '../../components/ui/styleUtils'; import {SvgImage} from '../../components/ui/svg'; -import {ProfileInfo} from '../../shared/googleCloudUtils'; +import {ProfileInfo} from '../../shared/CloudBackupAndRestoreUtils'; import {useBackupScreen} from './BackupController'; import {BannerNotificationContainer} from '../../components/BannerNotificationContainer'; import {useBackupRestoreScreen} from '../Settings/BackupRestoreController'; import {Icon} from 'react-native-elements'; -import testIDProps from '../../shared/commonUtil'; +import testIDProps, {getDriveName} from '../../shared/commonUtil'; import {HelpScreen} from '../../components/HelpScreen'; +import {isAndroid} from '../../shared/constants'; const BackupAndRestoreScreen: React.FC = props => { const backupController = useBackupScreen(); @@ -102,7 +103,7 @@ const BackupAndRestoreScreen: React.FC = props => { - {t('noBackup')} + {t('noBackup', {driveName: getDriveName()})} )} @@ -127,7 +128,7 @@ const BackupAndRestoreScreen: React.FC = props => { + headerIcon={SvgImage.GoogleDriveIconSmall(28, 25)}> = props => { ) : ( {LastBackupSection} - {AccountSection} + {isAndroid() && AccountSection} {RestoreSection} )} diff --git a/screens/backupAndRestore/BackupAndRestoreSetupController.ts b/screens/backupAndRestore/BackupAndRestoreSetupController.ts index 96fff7cd62..2535c1c623 100644 --- a/screens/backupAndRestore/BackupAndRestoreSetupController.ts +++ b/screens/backupAndRestore/BackupAndRestoreSetupController.ts @@ -18,18 +18,21 @@ import {selectIsBackUpAndRestoreExplored} from '../../machines/settings'; import {SettingsEvents} from '../../machines/settings'; export function useBackupAndRestoreSetup() { + const {appService} = useContext(GlobalContext); + const settingsService = appService.children.get('settings'); + const storeService = appService.children.get('store'); const machine = useRef( backupAndRestoreSetupMachine.withContext({ ...backupAndRestoreSetupMachine.context, + serviceRefs: {settings: settingsService, store: storeService}, }), ); const service = useInterpret(machine.current); - const {appService} = useContext(GlobalContext); - const settingsService = appService.children.get('settings'); const isBackupAndRestoreExplored = useSelector( settingsService, selectIsBackUpAndRestoreExplored, ); + return { isLoading: useSelector(service, selectIsLoading), profileInfo: useSelector(service, selectProfileInfo), @@ -51,14 +54,16 @@ export function useBackupAndRestoreSetup() { ); } }, - shouldTriggerAutoBackup: useSelector( - service, - selectShouldTriggerAutoBackup, - ), + shouldTriggerAutoBackup: useSelector( + service, + selectShouldTriggerAutoBackup, + ), PROCEED_ACCOUNT_SELECTION: () => service.send(BackupAndRestoreSetupEvents.PROCEED()), GO_BACK: () => service.send(BackupAndRestoreSetupEvents.GO_BACK()), TRY_AGAIN: () => service.send(BackupAndRestoreSetupEvents.TRY_AGAIN()), + OPEN_SETTINGS: () => + service.send(BackupAndRestoreSetupEvents.OPEN_SETTINGS()), DISMISS: () => service.send(BackupAndRestoreSetupEvents.DISMISS()), }; } diff --git a/shared/googleCloudUtils.ts b/shared/CloudBackupAndRestoreUtils.ts similarity index 67% rename from shared/googleCloudUtils.ts rename to shared/CloudBackupAndRestoreUtils.ts index e6d6589c25..774bbff468 100644 --- a/shared/googleCloudUtils.ts +++ b/shared/CloudBackupAndRestoreUtils.ts @@ -6,8 +6,13 @@ import {CloudStorage, CloudStorageScope} from 'react-native-cloud-storage'; import {GOOGLE_ANDROID_CLIENT_ID} from 'react-native-dotenv'; import {readFile, writeFile} from 'react-native-fs'; import {BackupDetails} from '../types/backup-and-restore/backup'; -import {bytesToMB} from './commonUtil'; -import {NETWORK_REQUEST_FAILED} from './constants'; +import {bytesToMB, sleep} from './commonUtil'; +import { + IOS_SIGNIN_FAILED, + isAndroid, + isIOS, + NETWORK_REQUEST_FAILED, +} from './constants'; import fileStorage, {backupDirectoryPath, zipFilePath} from './fileStorage'; import {request} from './request'; @@ -17,11 +22,17 @@ class Cloud { SUCCESS: 'SUCCESS', FAILURE: 'FAILURE', }; - static timeout = 10000; + static readonly timeout = 10000; private static readonly requiredScopes = [ 'https://www.googleapis.com/auth/drive.appdata', 'https://www.googleapis.com/auth/drive.file', ]; + private static readonly BACKUP_FILE_REG_EXP = /backup_[0-9]*.zip$/g; + private static readonly UNSYNCED_BACKUP_FILE_REG_EXP = + /backup_[0-9]*.zip.icloud/g; + private static readonly RETRY_SLEEP_TIME = 5000; + + static readonly NO_BACKUP_FILE = 'Backup files not available'; private static configure() { GoogleSignin.configure({ @@ -29,6 +40,7 @@ class Cloud { androidClientId: GOOGLE_ANDROID_CLIENT_ID, }); } + private static async profileInfo(): Promise { try { const accessToken = await this.getAccessToken(); @@ -47,6 +59,18 @@ class Cloud { throw error; } } + + private static getBackupFilesList = async () => { + return await CloudStorage.readdir(`/`, CloudStorageScope.AppData); + }; + + private static async syncBackupFiles() { + const isSyncDone = await this.downloadUnSyncedBackupFiles(); + if (isSyncDone) return; + await sleep(this.RETRY_SLEEP_TIME); + await this.syncBackupFiles(); + } + static async getAccessToken() { try { const tokenResult = await GoogleSignin.getTokens(); @@ -59,7 +83,11 @@ class Cloud { throw error; } } - static async signIn(): Promise { + + static async signIn(): Promise { + if (isIOS()) { + return {isIOS: true}; + } this.configure(); try { const {scopes: userProvidedScopes} = await GoogleSignin.signIn(); @@ -91,8 +119,15 @@ class Cloud { }; } } + static async isSignedInAlready(): Promise { try { + if (isIOS()) { + const isSignedIn = await CloudStorage.isCloudAvailable(); + return { + isSignedIn, + }; + } this.configure(); const isSignedIn = await GoogleSignin.isSignedIn(); if (!isSignedIn) { @@ -127,46 +162,68 @@ class Cloud { }; } } + + static async downloadUnSyncedBackupFiles(): Promise { + if (isIOS()) { + const unSyncedFiles = (await this.getBackupFilesList()).filter(file => + file.match(this.UNSYNCED_BACKUP_FILE_REG_EXP), + ); + if (unSyncedFiles.length > 0) { + await CloudStorage.downloadFile(`/${unSyncedFiles[0]}`); + return false; + } + } + return true; + } + static async lastBackupDetails( cloudFileName?: string | undefined, ): Promise { CloudStorage.setTimeout(this.timeout); - const tokenResult = await Cloud.getAccessToken(); - CloudStorage.setGoogleDriveAccessToken(tokenResult); + if (isAndroid()) { + const tokenResult = await Cloud.getAccessToken(); + CloudStorage.setGoogleDriveAccessToken(tokenResult); + } + if (isIOS()) { + const isCloudAvailable = await CloudStorage.isCloudAvailable(); + if (!isCloudAvailable) { + return Promise.reject({ + status: this.status.FAILURE, + error: IOS_SIGNIN_FAILED, + }); + } + await this.syncBackupFiles(); + } + if (!cloudFileName) { - const allFiles = await CloudStorage.readdir( - `/`, - CloudStorageScope.AppData, - ); - cloudFileName = allFiles[0]; + const availableBackupFilesInCloud = ( + await this.getBackupFilesList() + ).filter(file => file.match(this.BACKUP_FILE_REG_EXP)); + if (availableBackupFilesInCloud.length === 0) { + throw new Error(this.NO_BACKUP_FILE); + } + cloudFileName = availableBackupFilesInCloud[0]; } const {birthtimeMs: creationTime, size} = await CloudStorage.stat( cloudFileName, CloudStorageScope.AppData, ); - const backupDetails = { + + return { backupCreationTime: creationTime, backupFileSize: bytesToMB(size), }; - return backupDetails; } + static async removeOldDriveBackupFiles(fileName: string) { - const allFiles = await CloudStorage.readdir(`/`, CloudStorageScope.AppData); - const toBeRemovedFiles = allFiles.filter(file => file !== fileName); - console.log( - 'removeOldDriveBackupFiles toBeRemovedFiles ', - toBeRemovedFiles, - ); + const toBeRemovedFiles = (await this.getBackupFilesList()) + .filter(file => file !== fileName) + .filter(file => file.match(this.BACKUP_FILE_REG_EXP)); for (const oldFileName of toBeRemovedFiles) { - console.log('removing -> ', oldFileName); await CloudStorage.unlink(`/${oldFileName}`); } - const allFilesPost = await CloudStorage.readdir( - `/`, - CloudStorageScope.AppData, - ); - console.log('removeOldDriveBackupFiles allFiles ', allFilesPost); } + static async uploadBackupFileToDrive( fileName: string, retryCounter: number, @@ -184,8 +241,19 @@ class Cloud { try { CloudStorage.setTimeout(this.timeout); - const tokenResult = await Cloud.getAccessToken(); - CloudStorage.setGoogleDriveAccessToken(tokenResult); + if (isAndroid()) { + const tokenResult = await Cloud.getAccessToken(); + CloudStorage.setGoogleDriveAccessToken(tokenResult); + } + if (isIOS()) { + const isCloudAvailable = await CloudStorage.isCloudAvailable(); + if (!isCloudAvailable) { + return Promise.reject({ + status: this.status.FAILURE, + error: IOS_SIGNIN_FAILED, + }); + } + } const filePath = zipFilePath(fileName); const fileContent = await readFile(filePath, 'base64'); @@ -202,7 +270,6 @@ class Cloud { if (isFileUploaded) { const backupDetails = await this.lastBackupDetails(cloudFileName); - console.log('wrote to cloudFileName ', cloudFileName); await this.removeOldDriveBackupFiles(`${fileName}.zip`); return Promise.resolve({ status: this.status.SUCCESS, @@ -234,15 +301,29 @@ class Cloud { static async downloadLatestBackup(): Promise { try { CloudStorage.setTimeout(this.timeout); - const tokenResult = await Cloud.getAccessToken(); - CloudStorage.setGoogleDriveAccessToken(tokenResult); - const allFiles = await CloudStorage.readdir( - '/', - CloudStorageScope.AppData, - ); - console.log('allFiles ', allFiles); + if (isAndroid()) { + const tokenResult = await Cloud.getAccessToken(); + CloudStorage.setGoogleDriveAccessToken(tokenResult); + } + if (isIOS()) { + const isCloudAvailable = await CloudStorage.isCloudAvailable(); + if (!isCloudAvailable) { + return Promise.reject({ + status: this.status.FAILURE, + error: IOS_SIGNIN_FAILED, + }); + } + await this.syncBackupFiles(); + } // TODO: do basic sanity about this .zip file - const fileName = allFiles[0]; + const availableBackupFilesInCloud = ( + await this.getBackupFilesList() + ).filter(file => file.match(this.BACKUP_FILE_REG_EXP)); + if (availableBackupFilesInCloud.length === 0) { + throw new Error(Cloud.NO_BACKUP_FILE); + } + + const fileName = `/${availableBackupFilesInCloud[0]}`; const fileContent = await CloudStorage.readFile( fileName, CloudStorageScope.AppData, @@ -259,7 +340,6 @@ class Cloud { fileContent, 'base64', ); - console.log('successfully written the cloud downloaded zip file'); // return the path return Promise.resolve(fileName.split('.zip')[0]); } catch (error) { @@ -267,8 +347,11 @@ class Cloud { let downloadError; if (error.toString() === 'Error: NetworkError') { downloadError = NETWORK_REQUEST_FAILED; - } else if (error.code?.toString() === 'ERR_DIRECTORY_NOT_FOUND') { - downloadError = 'No backup file'; + } else if ( + error.code?.toString() === 'ERR_DIRECTORY_NOT_FOUND' || + error.toString().includes(this.NO_BACKUP_FILE) + ) { + downloadError = this.NO_BACKUP_FILE; } else { downloadError = error; } @@ -290,6 +373,10 @@ export type SignInResult = { error?: string; }; +export type IsIOSResult = { + isIOS?: boolean; +}; + export type isSignedInResult = { isSignedIn: boolean; error?: string | null; diff --git a/shared/commonUtil.ts b/shared/commonUtil.ts index 7e2a80c7de..66834f238c 100644 --- a/shared/commonUtil.ts +++ b/shared/commonUtil.ts @@ -1,7 +1,7 @@ import argon2 from 'react-native-argon2'; import {AnyState} from 'xstate'; import {getDeviceNameSync} from 'react-native-device-info'; -import {isAndroid} from './constants'; +import {GOOGLE_DRIVE_NAME, ICLOUD_DRIVE_NAME, isAndroid} from './constants'; import {generateSecureRandom} from 'react-native-securerandom'; import forge from 'node-forge'; @@ -107,3 +107,10 @@ export const bytesToMB = (bytes: number): string => { const megabytes = bytes / BYTES_IN_MEGABYTE; return Number(megabytes).toFixed(2); }; + +export const getDriveName = () => + isAndroid() ? GOOGLE_DRIVE_NAME : ICLOUD_DRIVE_NAME; + +export function sleep(time = 1000) { + return new Promise(resolve => setTimeout(resolve, time)); +} diff --git a/shared/constants.ts b/shared/constants.ts index 13bd6d816d..e94685d3c0 100644 --- a/shared/constants.ts +++ b/shared/constants.ts @@ -100,5 +100,8 @@ export type IndividualId = { export const TECHNICAL_ERROR = 'Technical error'; export const NETWORK_REQUEST_FAILED = 'Network request failed'; +export const IOS_SIGNIN_FAILED = 'iCloud not available'; export const REQUEST_TIMEOUT = 'request timedout'; export const BIOMETRIC_CANCELLED = 'User has cancelled biometric'; +export const GOOGLE_DRIVE_NAME = 'Google Drive'; +export const ICLOUD_DRIVE_NAME = 'iCloud'; From ff194ddb8901c7a47f12650f08781711d77136c3 Mon Sep 17 00:00:00 2001 From: Harsh Vardhan Date: Wed, 14 Feb 2024 13:46:21 +0530 Subject: [PATCH 14/37] [INJIMOB-787] Conditional restore of VCs (#120) * [INJI-787] add bootstrap state for restarting restore ops Notes: - all operations depend on the state of the $DOCUMENT_DIR/inji/backup/ directory contents and not on the state of the MMKV DB Signed-off-by: Harsh Vardhan * [INJI-787] conditional restore on restart of restore Signed-off-by: Harsh Vardhan * [INJIMOB-787] fix recent file finder code Signed-off-by: Harsh Vardhan * [INJIMOB-787] add vc remove logic for partial restore Signed-off-by: Harsh Vardhan * [INJIMOB-787] refactor, ACK reviews, rm dead condition Signed-off-by: Harsh Vardhan * [INJIMOB-787] remove console.logs Signed-off-by: Harsh Vardhan * [INJIMOB-787] remove irrelevant TODOs Signed-off-by: Harsh Vardhan --------- Signed-off-by: Harsh Vardhan --- .talismanrc | 14 ++- machines/VCItemMachine/vc.typegen.ts | 58 +++++------ machines/backupRestore.ts | 109 ++++++++++++++++---- machines/backupRestore.typegen.ts | 144 +++++++++------------------ shared/fileStorage.ts | 25 +++++ shared/storage.ts | 76 ++++++++++++-- 6 files changed, 268 insertions(+), 158 deletions(-) diff --git a/.talismanrc b/.talismanrc index ab80342432..a8df2036e0 100644 --- a/.talismanrc +++ b/.talismanrc @@ -36,7 +36,7 @@ fileignoreconfig: - filename: shared/telemetry/TelemetryUtils.js checksum: ffe9aac2dcc590b98b0d588885c088eff189504ade653a77f74b67312bfd27ad - filename: shared/fileStorage.ts - checksum: 451e8873a635d955fe426d9a5fcf191f2d4fd74984a1a4518760e2d10e9e1817 + checksum: 2ba2721d9722cd9420ae26762316230f7dab1a0be45820cbda4d0ecae0edf957 - filename: screens/Issuers/IssuersScreen.tsx checksum: 9c53e3770dbefe26e0de67ee4b7d5cc9c52d9823cbb136a1a5104dcb0a101071 - filename: ios/Podfile.lock @@ -122,7 +122,7 @@ fileignoreconfig: - filename: screens/Settings/BackupController.tsx checksum: 4a031b46646aa982c8f40e4c7fe0bd3e05a76a6af1ff1c2de7350ba6ebf9a839 - filename: machines/backupRestore.typegen.ts - checksum: 67925a7ee485ab3ba4c6345340ad6598746717984c0506f1ced1716fb68b5aa4 + checksum: ac9c154060c7c1adb3392ac8c78a42cae5ca3faea3b4b0166dd00d4ca38b290d - filename: machines/settings.typegen.ts checksum: e4ae05822f1b1c23f3f70d03dd46fd8f29ba6b52d40f2f24c121f536fbb5f2c4 - filename: .env @@ -140,7 +140,7 @@ fileignoreconfig: - filename: ios/fastlane/Fastfile checksum: a4e3772dc67a07ecbcfc58be0d6d4f7fa799cec7ac25bd269ac29459c8669ca4 - filename: shared/storage.ts - checksum: c0e99e00d260c665dcf87d09b1ed75a4e73cb9eeb2036ccb021560d1d643489f + checksum: c83024929b59f76cce188dbe09eb3af1803d3a08f867feb7478137ddabc3bfdc - filename: injitest/src/test/java/iosTestCases/CredentialRegistryTest.java checksum: b0808e0c511412cde21fd169a9bbeaf3b77cb48f25418e12d341cc3ce1df5898 - filename: machines/backupAndRestore/backupAndRestore.typegen.ts @@ -181,10 +181,14 @@ fileignoreconfig: - filename: components/HelpScreen.tsx checksum: bbc69143bd37d065bba3800396301db5a0318e8b7ba51ecd49142dda68783a01 - filename: machines/backupRestore.ts - checksum: 94bbbe550c3e6ba77f66252fc62e9659236ce880bca44fc05f5bd8170e9c6388 + checksum: 433cecb9295c7052731600d16c601c1b6df9cc5a1b9f435423f81aae54d33d47 + - filename: machines/backupAndRestore/backupAndRestoreSetup.ts + checksum: 75b07071aef4278f40f16861232b922e5ee8594efc9467984b072966fa7793b8 - filename: machines/backupAndRestore/backupAndRestoreSetup.typegen.ts checksum: ad12de520a68fbd43560474ded24edf25a02f6ec90b67c726d6c5dedb579eb83 - filename: machines/backupAndRestore/backupAndRestoreSetup.ts - checksum: 1822e1966c97649cf9ee8892fbca143128003234d59ca754e0527feaf769f162 + checksum: 397f2076504f851a981b0deff6eeac30041c775ee1c57b51e328fc09d52ef43e + - filename: shared/VCMetadata.ts + checksum: e93f988415bf91064e2cf5fbc09ff6c7226798baa5da721fa0715d5d0d6afddf version: "" diff --git a/machines/VCItemMachine/vc.typegen.ts b/machines/VCItemMachine/vc.typegen.ts index c570831fef..91cf9a917d 100644 --- a/machines/VCItemMachine/vc.typegen.ts +++ b/machines/VCItemMachine/vc.typegen.ts @@ -3,7 +3,7 @@ export interface Typegen0 { '@@xstate/typegen': true; internalEvents: { - 'xstate.init': {type: 'xstate.init'}; + 'xstate.init': { type: 'xstate.init' }; }; invokeSrcNameMap: {}; missingImplementations: { @@ -17,11 +17,11 @@ export interface Typegen0 { getReceivedVcsResponse: 'GET_RECEIVED_VCS'; getVcItemResponse: 'GET_VC_ITEM'; loadMyVcs: - | 'DOWNLOAD_LIMIT_EXPIRED' - | 'REFRESH_MY_VCS' - | 'REMOVE_TAMPERED_VCS' - | 'STORE_RESPONSE' - | 'xstate.init'; + | 'DOWNLOAD_LIMIT_EXPIRED' + | 'REFRESH_MY_VCS' + | 'REMOVE_TAMPERED_VCS' + | 'STORE_RESPONSE' + | 'xstate.init'; loadReceivedVcs: 'REFRESH_RECEIVED_VCS' | 'STORE_RESPONSE'; logTamperedVCsremoved: 'REMOVE_TAMPERED_VCS'; prependToMyVcs: 'VC_ADDED'; @@ -30,8 +30,8 @@ export interface Typegen0 { removeDownloadingFailedVcsFromMyVcs: 'STORE_RESPONSE'; removeTamperedVcs: 'REMOVE_TAMPERED_VCS'; removeVcFromInProgressDownlods: - | 'DOWNLOAD_LIMIT_EXPIRED' - | 'REMOVE_VC_FROM_IN_PROGRESS_DOWNLOADS'; + | 'DOWNLOAD_LIMIT_EXPIRED' + | 'REMOVE_VC_FROM_IN_PROGRESS_DOWNLOADS'; removeVcFromMyVcs: 'REMOVE_VC_FROM_CONTEXT'; resetAreAllVcsDownloaded: 'RESET_ARE_ALL_VCS_DOWNLOADED'; resetDownloadFailedVcs: 'STORE_RESPONSE'; @@ -50,27 +50,27 @@ export interface Typegen0 { eventsCausingGuards: {}; eventsCausingServices: {}; matchesStates: - | 'deletingFailedVcs' - | 'init' - | 'init.myVcs' - | 'init.receivedVcs' - | 'ready' - | 'ready.myVcs' - | 'ready.myVcs.idle' - | 'ready.myVcs.refreshing' - | 'ready.receivedVcs' - | 'ready.receivedVcs.idle' - | 'ready.receivedVcs.refreshing' - | 'tamperedVCs' + | 'deletingFailedVcs' + | 'init' + | 'init.myVcs' + | 'init.receivedVcs' + | 'ready' + | 'ready.myVcs' + | 'ready.myVcs.idle' + | 'ready.myVcs.refreshing' + | 'ready.receivedVcs' + | 'ready.receivedVcs.idle' + | 'ready.receivedVcs.refreshing' + | 'tamperedVCs' + | { + init?: 'myVcs' | 'receivedVcs'; + ready?: + | 'myVcs' + | 'receivedVcs' | { - init?: 'myVcs' | 'receivedVcs'; - ready?: - | 'myVcs' - | 'receivedVcs' - | { - myVcs?: 'idle' | 'refreshing'; - receivedVcs?: 'idle' | 'refreshing'; - }; - }; + myVcs?: 'idle' | 'refreshing'; + receivedVcs?: 'idle' | 'refreshing'; + }; + }; tags: never; } diff --git a/machines/backupRestore.ts b/machines/backupRestore.ts index 2b3889e117..8cd6756d53 100644 --- a/machines/backupRestore.ts +++ b/machines/backupRestore.ts @@ -1,15 +1,16 @@ -import {EventFrom, StateFrom, send} from 'xstate'; -import {createModel} from 'xstate/lib/model'; -import {AppServices} from '../shared/GlobalContext'; +import { EventFrom, StateFrom, send } from 'xstate'; +import { createModel } from 'xstate/lib/model'; +import { AppServices } from '../shared/GlobalContext'; import fileStorage, { backupDirectoryPath, + findMostRecentBackupFile, getBackupFilePath, unZipAndRemoveFile, } from '../shared/fileStorage'; import Storage from '../shared/storage'; -import {StoreEvents} from './store'; +import { StoreEvents } from './store'; import Cloud from '../shared/CloudBackupAndRestoreUtils'; -import {TelemetryConstants} from '../shared/telemetry/TelemetryConstants'; +import { TelemetryConstants } from '../shared/telemetry/TelemetryConstants'; import { sendStartEvent, getStartEventData, @@ -18,8 +19,8 @@ import { sendEndEvent, getEndEventData, } from '../shared/telemetry/TelemetryUtils'; -import {VcEvents} from './VCItemMachine/vc'; -import {NETWORK_REQUEST_FAILED, TECHNICAL_ERROR} from '../shared/constants'; +import { VcEvents } from './VCItemMachine/vc'; +import { NETWORK_REQUEST_FAILED, TECHNICAL_ERROR } from '../shared/constants'; const model = createModel( { @@ -34,9 +35,9 @@ const model = createModel( DOWNLOAD_UNSYNCED_BACKUP_FILES: () => ({}), EXTRACT_DATA: () => ({}), DISMISS: () => ({}), - STORE_RESPONSE: (response: unknown) => ({response}), - STORE_ERROR: (error: Error, requester?: string) => ({error, requester}), - DATA_FROM_FILE: (dataFromBackupFile: {}) => ({dataFromBackupFile}), + STORE_RESPONSE: (response: unknown) => ({ response }), + STORE_ERROR: (error: Error, requester?: string) => ({ error, requester }), + DATA_FROM_FILE: (dataFromBackupFile: {}) => ({ dataFromBackupFile }), OK: () => ({}), }, }, @@ -46,6 +47,7 @@ export const BackupRestoreEvents = model.events; export const backupRestoreMachine = model.createMachine( { + /** @xstate-layout N4IgpgJg5mDOIC5QCMCGBjA1gVwA4CU4AXAewCcwBiAIQEEBhAaQFUAFAfXwFEBlAFQDy3ANoAGALqJQuErACWROSQB2UkAA9EAFgBMAGhABPRAA4AjADoAzDp0BOUVt0BWAGwB2d1ucBfHwbQsPEJYUgoLXAoAGxJUCEoIFTALOWUANxJMZMCcAmJyZMiwGLiEVIz0VEUVMXFatRl5atUkDUQrUXcLMy07dx1ndzMrMzNRE2cDYwQzHVErC1crdzcTLVce1xMdPwCMXJCw5NSFGgYWDm5+IS561saFJRbQTQRXfSN23W6tNd07KwTOx2My7EA5YL5cIUUIFaj7PCUASMO7SWSPFRqV59KamOxaCx2ZzrKxbdwmUSjExgiF5WHQqFgeFBXCUAAiAEkeABZLk8VEgB7NLHtPomCzrZyiTpDHQmClaXEIYF2CwTdyieyifEdMzuGkIulHCwwo7M3KULgADT4+AYfHYbNofFoAqFTxFyvcSrsJlV6s1Dh1lP1-nBhsOBRNjPNeAs6AAFmAsDwwqgYLQ0qg5FE5MgcwpDAkkil0plshHGdH6UzDfGkym0xmswX87miIYymXKs1am70cLWq9BjpCU5A-0tPMJkrnB01WszK5fvMOlY7AaWZGGTXY7h68nMKnyOmwJns7m24Xi8pjmWshZadvkqa4XXE4fj2RT+fWwWO12FRVE8fZmJI9wDh6Q6ICOY5TvYk7TpMnwzNKqogpqYzOD0zgmFYvhhk+VavhQe4WIkADuyglBAe4AGI5mAdFkCQAC29AxNg8SJLepYZA+RE1tWZp1pR1GxLRhoMVETEsexnEQIBJA9iBEj9k0UEvIgZjYZYZh2DongDPi2x6kqYyUhKojElo672LYgKbgcxExqJJBUTR9GMcxbEcSQXGUGAZAsWQERRFUABm5CsY+lZCSRtYsuR7niXEXkyT58n+Yp5TKcBNRqRIDSQZi0EzLp3QGUZzgmToZkoR4o7OHM8qAnY7yzNShFxcaCVkdgygAF5yLg6VUDxd78RWW4ubudYDcNo1SYxSkqQVdRFRBGmlVpMzAq4FiOB0riiMu2qneZ07WL0rVBroVhaE5kLxa5SULSNY2BcF5BhZF0WxTNL1zW9Q0fctMmrflyh9ptaLbc8bR7e1h22adp1Tg4rhKuYBI6e4J32H6sxmF1eyA71r25NGaXg1QTouuwdH4AI3KMxyAAytyw4KJUI68Oi2c4Fg6PhFKdNOJjeihYw9N0AvvEMFIjDs3Xk1GfV1jRbJVKgfAkNyYCseQRbXNwnC8KwAgAHI8Fz4FwxifOIHKvpqkuc7te4gK4Zd2GHa4mNDCdumuE9Rrq5TcZazresG0bZAm4IZtcPgzP4Opjuei74rmK4HseN7Jg+s4QvuDqtjjHMHShmTzlAyJSUQMUYBEIluRsnIZA3pN5YA3XFPA1TTcya3e4d2QkO9oV9s8-DnoPVolgnUSVjrg4RmKtLgZqt4oxewLp34X4YbKCQTfwK0glHMVc9lQAtFjKEP2Hz4RNEEk35nZW6OZS4LD0PRdCS1snnKwL8qwnCIJ-Qcu1F6agsBqGwfp1yOBBJdeBzUpRTm1HMPOG5Vb9wjoPPA0DNKI16EqJwCw3DEzqkSaywJwH1zfElOQEAZKkJ2ojQyQsdAbC9kuEmzUdKb2mH6IWsxjLkmwavGu4Y1Y7gblTD8jYTzNgvHmf80wHYwO4SsYW-CRgbAmHVYkxcFgbFsIAl2owwEEOegPJRcYxKeVpplPyXFOFOxmLYA6KwQR9C9vwouKFfQSPeLnEWAs5xMMcSwqm70losmkmALxno9TLmFuuAuCoTCuDzj6YE1hth53sr6fopN5GEMUfEuMFAabJMYmksqFdVSOFsuSWw+JLrDEWJqX47VDJlNiUQpx+5o5EF1vrQ2xtmm7T4c1awgIPDTi0EMRwPSLH9L9ArYZ9jw41NIqJZuo9DTjzmYjEYZdFg3UlgHCYy5LqGTVLYXQSx2r6TkVfUZtT9ywGwOgdAcAL46LIa8Uk9gEEeDGAM34WEnldG2LYewRIiRl0qd8w5bc4wRQvNgCgFzwXDGoQHPUlI5gDG8NjeY3R5h0ususykx8fBAA */ predictableActionArguments: true, preserveActionOrder: true, tsTypes: {} as import('./backupRestore.typegen').Typegen0, @@ -54,18 +56,24 @@ export const backupRestoreMachine = model.createMachine( events: {} as EventFrom, }, id: 'backupRestore', - initial: 'init', - on: { - BACKUP_RESTORE: [ - { - target: 'restoreBackup', + initial: 'preload', + states: { + preload: { + description: + 'runs all pending restore migrations based on the state of the filestorage', + invoke: { + src: 'bootstrap', + onDone: [ + { + cond: 'isBackupFile', + target: 'restoreBackup.readBackupFile', + }, + { + target: 'init', + }, + ], }, - ], - DOWNLOAD_UNSYNCED_BACKUP_FILES: { - actions: 'downloadUnsyncedBackupFiles', }, - }, - states: { init: { on: { BACKUP_RESTORE: [ @@ -73,6 +81,9 @@ export const backupRestoreMachine = model.createMachine( target: 'restoreBackup', }, ], + DOWNLOAD_UNSYNCED_BACKUP_FILES: { + actions: 'downloadUnsyncedBackupFiles', + }, }, }, restoreBackup: { @@ -198,7 +209,7 @@ export const backupRestoreMachine = model.createMachine( context => { return StoreEvents.RESTORE_BACKUP(context.dataFromBackupFile); }, - {to: context => context.serviceRefs.store}, + { to: context => context.serviceRefs.store }, ), refreshVCs: send(VcEvents.REFRESH_MY_VCS, { to: context => context.serviceRefs.vc, @@ -241,11 +252,53 @@ export const backupRestoreMachine = model.createMachine( }, services: { + bootstrap: context => async () => { + const bkpDIR = await fileStorage.exists(backupDirectoryPath); + // 1. Does anything even exists? + if (!bkpDIR) { + // noop: nothing exists, quit + return ''; + } + // 2. Check for .injibackup file + const bkpFile = await findMostRecentBackupFile( + backupDirectoryPath, + 'injibackup', + ); + if (bkpFile !== '') { + context.fileName = bkpFile; + return context.fileName; + } + // 3. Check for .zip files + const ZIPfile = await findMostRecentBackupFile(); + if (ZIPfile === '') { + return ''; + } + // go to loadBackupFile + // 4. Check for corrupted ZIP + let filePath = ''; + try { + (filePath = await unZipAndRemoveFile(ZIPfile.split('.zip')[0])), + (context.fileName = filePath.split('/inji/backup/')[1]); + return getFileNameFromZIPfile(context.fileName); + } catch (_) { + console.log('got error during unzip deleting the zip'); + await fileStorage.removeItem(backupDirectoryPath); + /* + Android Errors: + - Couldn’t open file... + - Failed to extract file... + iOS Errors: + - unzip_error... + */ + return ''; + } + }, checkStorageAvailability: () => async () => { return await Storage.isMinimumLimitReached('minStorageRequired'); }, deleteBkpDir: () => async () => - fileStorage.removeItem(backupDirectoryPath), + (await fileStorage.exists(backupDirectoryPath)) && + (await fileStorage.removeItem(backupDirectoryPath)), downloadLatestBackup: () => async () => { const backupFileName = await Cloud.downloadLatestBackup(); @@ -259,6 +312,10 @@ export const backupRestoreMachine = model.createMachine( return await unZipAndRemoveFile(context.fileName); }, readBackupFile: context => async callback => { + // trim extension + context.fileName = context.fileName.endsWith('.injibackup') + ? context.fileName.split('.injibackup')[0] + : context.fileName; const dataFromBackupFile = await fileStorage.readFile( getBackupFilePath(context.fileName), ); @@ -267,6 +324,7 @@ export const backupRestoreMachine = model.createMachine( }, guards: { + isBackupFile: (_, event) => event.data.endsWith('.injibackup'), isMinimumStorageRequiredForBackupRestorationReached: (_context, event) => Boolean(event.data), }, @@ -299,3 +357,10 @@ export function selectIsBackUpRestoreFailure(state: State) { return state.matches('restoreBackup.failure'); } type State = StateFrom; + +function getFileNameFromZIPfile(fileName: string): string { + if (fileName.endsWith('.zip')) { + return fileName.split('.zip')[0] + '.injibackup'; + } + return fileName + '.injiBackup'; +} diff --git a/machines/backupRestore.typegen.ts b/machines/backupRestore.typegen.ts index 5bc2e1bd68..e2bb7d250a 100644 --- a/machines/backupRestore.typegen.ts +++ b/machines/backupRestore.typegen.ts @@ -1,105 +1,59 @@ + // This file was automatically generated. Edits will be overwritten export interface Typegen0 { - '@@xstate/typegen': true; - internalEvents: { - 'done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]': { - type: 'done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]'; - data: unknown; - __tip: 'See the XState TS docs to learn how to strongly type this.'; + '@@xstate/typegen': true; + internalEvents: { + "done.invoke.backupRestore.preload:invocation[0]": { type: "done.invoke.backupRestore.preload:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." }; + "done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]": { type: "done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." }; + "done.invoke.backupRestore.restoreBackup.deleteBackupDir:invocation[0]": { type: "done.invoke.backupRestore.restoreBackup.deleteBackupDir:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." }; + "done.invoke.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]": { type: "done.invoke.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." }; + "done.invoke.backupRestore.restoreBackup.unzipBackupFile:invocation[0]": { type: "done.invoke.backupRestore.restoreBackup.unzipBackupFile:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." }; + "error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]": { type: "error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]"; data: unknown }; + "error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]": { type: "error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]"; data: unknown }; + "xstate.init": { type: "xstate.init" }; + }; + invokeSrcNameMap: { + "bootstrap": "done.invoke.backupRestore.preload:invocation[0]"; + "checkStorageAvailability": "done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]"; + "deleteBkpDir": "done.invoke.backupRestore.restoreBackup.deleteBackupDir:invocation[0]"; + "downloadLatestBackup": "done.invoke.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]"; + "readBackupFile": "done.invoke.backupRestore.restoreBackup.readBackupFile:invocation[0]"; + "unzipBackupFile": "done.invoke.backupRestore.restoreBackup.unzipBackupFile:invocation[0]"; }; - 'done.invoke.backupRestore.restoreBackup.deleteBackupDir:invocation[0]': { - type: 'done.invoke.backupRestore.restoreBackup.deleteBackupDir:invocation[0]'; - data: unknown; - __tip: 'See the XState TS docs to learn how to strongly type this.'; + missingImplementations: { + actions: never; + delays: never; + guards: never; + services: never; }; - 'done.invoke.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]': { - type: 'done.invoke.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]'; - data: unknown; - __tip: 'See the XState TS docs to learn how to strongly type this.'; + eventsCausingActions: { + "downloadUnsyncedBackupFiles": "DOWNLOAD_UNSYNCED_BACKUP_FILES"; + "loadDataToMemory": "DATA_FROM_FILE"; + "refreshVCs": "done.invoke.backupRestore.restoreBackup.deleteBackupDir:invocation[0]"; + "sendDataRestoreFailureEvent": "STORE_ERROR" | "done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]" | "error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]" | "error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]"; + "sendDataRestoreStartEvent": "BACKUP_RESTORE" | "EXTRACT_DATA" | "done.invoke.backupRestore.preload:invocation[0]"; + "sendDataRestoreSuccessEvent": "done.invoke.backupRestore.restoreBackup.deleteBackupDir:invocation[0]"; + "setBackupFileName": "done.invoke.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]"; + "setDataFromBackupFile": "DATA_FROM_FILE"; + "setRestoreErrorReason": "error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]" | "error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]"; + "setRestoreTechnicalError": "STORE_ERROR" | "done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]"; }; - 'done.invoke.backupRestore.restoreBackup.unzipBackupFile:invocation[0]': { - type: 'done.invoke.backupRestore.restoreBackup.unzipBackupFile:invocation[0]'; - data: unknown; - __tip: 'See the XState TS docs to learn how to strongly type this.'; + eventsCausingDelays: { + }; - 'error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]': { - type: 'error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]'; - data: unknown; + eventsCausingGuards: { + "isBackupFile": "done.invoke.backupRestore.preload:invocation[0]"; + "isMinimumStorageRequiredForBackupRestorationReached": "done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]"; }; - 'error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]': { - type: 'error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]'; - data: unknown; + eventsCausingServices: { + "bootstrap": "xstate.init"; + "checkStorageAvailability": "BACKUP_RESTORE" | "EXTRACT_DATA" | "done.invoke.backupRestore.preload:invocation[0]"; + "deleteBkpDir": "STORE_RESPONSE"; + "downloadLatestBackup": "done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]"; + "readBackupFile": "done.invoke.backupRestore.preload:invocation[0]" | "done.invoke.backupRestore.restoreBackup.unzipBackupFile:invocation[0]"; + "unzipBackupFile": "done.invoke.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]"; }; - 'xstate.init': {type: 'xstate.init'}; - }; - invokeSrcNameMap: { - checkStorageAvailability: 'done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]'; - deleteBkpDir: 'done.invoke.backupRestore.restoreBackup.deleteBackupDir:invocation[0]'; - downloadLatestBackup: 'done.invoke.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]'; - readBackupFile: 'done.invoke.backupRestore.restoreBackup.readBackupFile:invocation[0]'; - unzipBackupFile: 'done.invoke.backupRestore.restoreBackup.unzipBackupFile:invocation[0]'; - }; - missingImplementations: { - actions: never; - delays: never; - guards: never; - services: never; - }; - eventsCausingActions: { - downloadUnsyncedBackupFiles: 'DOWNLOAD_UNSYNCED_BACKUP_FILES'; - loadDataToMemory: 'DATA_FROM_FILE'; - refreshVCs: 'done.invoke.backupRestore.restoreBackup.deleteBackupDir:invocation[0]'; - sendDataRestoreFailureEvent: - | 'STORE_ERROR' - | 'done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]' - | 'error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]' - | 'error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]'; - sendDataRestoreStartEvent: 'BACKUP_RESTORE' | 'EXTRACT_DATA'; - sendDataRestoreSuccessEvent: 'done.invoke.backupRestore.restoreBackup.deleteBackupDir:invocation[0]'; - setBackupFileName: 'done.invoke.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]'; - setDataFromBackupFile: 'DATA_FROM_FILE'; - setRestoreErrorReason: - | 'error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]' - | 'error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]'; - setRestoreTechnicalError: - | 'STORE_ERROR' - | 'done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]'; - }; - eventsCausingDelays: {}; - eventsCausingGuards: { - isMinimumStorageRequiredForBackupRestorationReached: 'done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]'; - }; - eventsCausingServices: { - checkStorageAvailability: 'BACKUP_RESTORE' | 'EXTRACT_DATA'; - deleteBkpDir: 'STORE_RESPONSE'; - downloadLatestBackup: 'done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]'; - readBackupFile: 'done.invoke.backupRestore.restoreBackup.unzipBackupFile:invocation[0]'; - unzipBackupFile: 'done.invoke.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]'; - }; - matchesStates: - | 'init' - | 'restoreBackup' - | 'restoreBackup.checkStorageAvailability' - | 'restoreBackup.deleteBackupDir' - | 'restoreBackup.downloadBackupFileFromCloud' - | 'restoreBackup.failure' - | 'restoreBackup.idle' - | 'restoreBackup.loadDataToMemory' - | 'restoreBackup.readBackupFile' - | 'restoreBackup.success' - | 'restoreBackup.unzipBackupFile' - | { - restoreBackup?: - | 'checkStorageAvailability' - | 'deleteBackupDir' - | 'downloadBackupFileFromCloud' - | 'failure' - | 'idle' - | 'loadDataToMemory' - | 'readBackupFile' - | 'success' - | 'unzipBackupFile'; - }; - tags: never; + matchesStates: "init" | "preload" | "restoreBackup" | "restoreBackup.checkStorageAvailability" | "restoreBackup.deleteBackupDir" | "restoreBackup.downloadBackupFileFromCloud" | "restoreBackup.failure" | "restoreBackup.idle" | "restoreBackup.loadDataToMemory" | "restoreBackup.readBackupFile" | "restoreBackup.success" | "restoreBackup.unzipBackupFile" | { "restoreBackup"?: "checkStorageAvailability" | "deleteBackupDir" | "downloadBackupFileFromCloud" | "failure" | "idle" | "loadDataToMemory" | "readBackupFile" | "success" | "unzipBackupFile"; }; + tags: never; } diff --git a/shared/fileStorage.ts b/shared/fileStorage.ts index 01b3f5a780..9b81e24e88 100644 --- a/shared/fileStorage.ts +++ b/shared/fileStorage.ts @@ -49,6 +49,11 @@ class FileStorage { return await unlink(path); } + async removeItemIfExist(path: string) { + const res = await exists(path); + return res && (await unlink(path)); + } + async getInfo(path: string) { return await stat(path); } @@ -78,6 +83,26 @@ export const getBackupFilePath = ( return `${backupDirectoryPath}/${key}${extension}`; }; +/** + * given a directory find the most recent backup file in the directory + * @param path the fully qualified path of the directory where ZIP files need + * to be found + */ +export async function findMostRecentBackupFile( + path: string = backupDirectoryPath, + extension: string = 'zip', +): Promise { + try { + const extSuffix = '.' + extension; + let files = await readDir(backupDirectoryPath); + const zipFiles = files.filter(f => f.name.endsWith(extSuffix)); + // sort() and return the latest one + return zipFiles[0].name; + } catch (_) { + return ''; + } +} + export async function compressAndRemoveFile( fileNameSansExtension: string, ): Promise { diff --git a/shared/storage.ts b/shared/storage.ts index 878fd6091e..fc862d4cf9 100644 --- a/shared/storage.ts +++ b/shared/storage.ts @@ -24,11 +24,14 @@ import FileStorage, { getFilePath, getDirectorySize, vcDirectoryPath, + backupDirectoryPath, } from './fileStorage'; import {__AppId} from './GlobalVariables'; import {getErrorEventData, sendErrorEvent} from './telemetry/TelemetryUtils'; import {TelemetryConstants} from './telemetry/TelemetryConstants'; import {BYTES_IN_MEGABYTE} from './commonUtil'; +import fileStorage from './fileStorage'; +import {DocumentDirectoryPath, ReadDirItem} from 'react-native-fs'; export const MMKV = new MMKVLoader().initialize(); @@ -60,7 +63,7 @@ class Storage { const keysToBeExported = allKeysInDB.filter(key => key.includes('CACHE_FETCH_ISSUER_WELLKNOWN_CONFIG_'), ); - keysToBeExported.push(MY_VCS_STORE_KEY); + keysToBeExported?.push(MY_VCS_STORE_KEY); const encryptedDataPromises = keysToBeExported.map(key => MMKV.getItem(key), @@ -117,12 +120,26 @@ class Storage { static loadBackupData = async (data, encryptionKey) => { try { + // 0. check for previous backup states + const prevBkpState = `${DocumentDirectoryPath}/.prev`; + const previousBackupExists = await fileStorage.exists(prevBkpState); + let previousRestoreTimestamp: string = ''; + if (previousBackupExists) { + // 0. Remove partial restored files + previousRestoreTimestamp = await fileStorage.readFile(prevBkpState); + previousRestoreTimestamp = previousRestoreTimestamp.trim(); + this.unloadVCs(encryptionKey, parseInt(previousRestoreTimestamp)); + } // 1. opening the file const completeBackupData = JSON.parse(data); // 2. Load and store VC_records & MMKV things + const backupStartState = Date.now().toString(); + // record the state to help with cleanup activities post partial backup + await fileStorage.writeFile(prevBkpState, backupStartState); const dataFromDB = await Storage.loadVCs( completeBackupData, encryptionKey, + backupStartState, ); // 3. Update the Well Known configs of the VCs const allKeysFromDB = Object.keys(dataFromDB); @@ -230,31 +247,75 @@ class Storage { } }; - private static async loadVCs(completeBackupData: any, encryptionKey: any) { + /** + * unloadVCs will remove a set of VCs against a particular timestamp + * + * @param timestamp the timestamp of the VCs + */ + private static async unloadVCs(encryptionKey: any, timestamp: number) { + // 1. Find the VCs in the inji directory which have the said timestamp + const file: ReadDirItem[] = await fileStorage.getAllFilesInDirectory( + `${DocumentDirectoryPath}/inji/VC/`, + ); + for (let i = 0; i < file.length; i++) { + const f = file[i]; + if (f.name.includes(timestamp.toString())) { + await fileStorage.removeItem(f.path); + } + } + // TODO: should this be done via the Store state machine to avoid popups? + // 3. Remove the keys from MMKV which have the same timestamp + let myVCsEnc = await MMKV.getItem(MY_VCS_STORE_KEY, encryptionKey); + if (myVCsEnc !== null) { + let mmkvVCs = await decryptJson(encryptionKey, myVCsEnc); + let vcList: VCMetadata[] = JSON.parse(mmkvVCs); + let newVCList: VCMetadata[] = []; + vcList.forEach(d => { + if (d.timestamp && parseInt(d.timestamp) !== timestamp) { + newVCList.push(d); + } + }); + const finalVC = await encryptJson( + encryptionKey, + JSON.stringify(newVCList), + ); + await MMKV.setItem(MY_VCS_STORE_KEY, finalVC); + } + } + + private static async loadVCs( + completeBackupData: {}, + encryptionKey: any, + timestamp: string, + ) { const allVCs = completeBackupData['VC_Records']; const allVCKeys = Object.keys(allVCs); const dataFromDB = completeBackupData['dataFromDB']; - + // 0. Check for VC presense in the store + // 1. store the VCs and the HMAC allVCKeys.forEach(async key => { let vc = allVCs[key]; - const currentUnixTimeStamp = Date.now(); + const ts = parseInt(timestamp); const prevUnixTimeStamp = vc.vcMetadata.timestamp; - vc.vcMetadata.timestamp = currentUnixTimeStamp; + vc.vcMetadata.timestamp = ts; dataFromDB.myVCs.forEach(myVcMetadata => { if ( myVcMetadata.requestId === vc.vcMetadata.requestId && myVcMetadata.timestamp === prevUnixTimeStamp ) { - myVcMetadata.timestamp = currentUnixTimeStamp; + myVcMetadata.timestamp = ts; } }); const updatedVcKey = new VCMetadata(vc.vcMetadata).getVcKey(); const encryptedVC = await encryptJson(encryptionKey, JSON.stringify(vc)); + const tmp = VCMetadata.fromVC(key); + // Save the VC to disk await this.setItem(updatedVcKey, encryptedVC, encryptionKey); }); + // 2. Update myVCsKey const dataFromMyVCKey = dataFromDB[MY_VCS_STORE_KEY]; const encryptedMyVCKeyFromMMKV = await MMKV.getItem(MY_VCS_STORE_KEY); - let newDataForMyVCKey; + let newDataForMyVCKey: VCMetadata[] = []; if (encryptedMyVCKeyFromMMKV != null) { const myVCKeyFromMMKV = await decryptJson( encryptionKey, @@ -273,6 +334,7 @@ class Storage { encryptedDataForMyVCKey, encryptionKey, ); + await fileStorage.removeItemIfExist(`${DocumentDirectoryPath}/.prev`); return dataFromDB; } From 8c6b8d50b42db50693cf913a03c4f5ae662c80e8 Mon Sep 17 00:00:00 2001 From: Vijay <94220135+vijay151096@users.noreply.github.com> Date: Wed, 14 Feb 2024 14:10:54 +0530 Subject: [PATCH 15/37] Revert "Inji mob 737 rtl issue (#1238)" This reverts commit 2665cdeee193d7fb428fc10354f30cc25084b83d. --- components/ui/themes/DefaultTheme.ts | 23 ++----- components/ui/themes/PurpleTheme.ts | 23 ++----- routes/main.ts | 6 +- screens/History/HistoryScreen.tsx | 3 +- screens/HomeScreenLayout.tsx | 75 +++++++++++----------- screens/MainLayout.tsx | 7 +- screens/Request/RequestLayout.tsx | 50 ++------------- screens/Request/RequestLayoutController.ts | 1 - screens/Scan/ScanLayout.tsx | 41 +++--------- screens/Scan/ScanScreen.tsx | 16 +++-- screens/Scan/ScanScreenController.ts | 8 +-- 11 files changed, 80 insertions(+), 173 deletions(-) diff --git a/components/ui/themes/DefaultTheme.ts b/components/ui/themes/DefaultTheme.ts index 393a4c15a3..f6cfa150be 100644 --- a/components/ui/themes/DefaultTheme.ts +++ b/components/ui/themes/DefaultTheme.ts @@ -431,7 +431,6 @@ export const DefaultTheme = { height: 36, borderRadius: 10, backgroundColor: Colors.LightOrange, - justifyContent: 'center', }, cameraFlipIcon: { height: 42, @@ -490,6 +489,10 @@ export const DefaultTheme = { paddingVertical: 9, justifyContent: 'space-between', }, + iconContainer: { + flexDirection: 'row', + alignItems: 'flex-end', + }, scannerContainer: { borderRadius: 24, alignSelf: 'center', @@ -670,24 +673,6 @@ export const DefaultTheme = { fontFamily: 'Inter_700Bold', lineHeight: 12, }, - scanLayoutHeaderContainer: { - flex: 1, - flexDirection: 'row', - marginLeft: I18nManager.isRTL ? 40 : 15, - marginTop: 15, - }, - scanLayoutHeaderTitle: { - fontSize: 26, - fontFamily: 'Inter_600SemiBold', - paddingTop: 20, - paddingBottom: 10, - }, - sendVcHeaderContainer: { - flex: 1, - flexDirection: 'row', - marginLeft: I18nManager.isRTL ? 50 : 0, - marginTop: 15, - }, }), BannerStyles: StyleSheet.create({ container: { diff --git a/components/ui/themes/PurpleTheme.ts b/components/ui/themes/PurpleTheme.ts index 2d0971c700..5a09846d14 100644 --- a/components/ui/themes/PurpleTheme.ts +++ b/components/ui/themes/PurpleTheme.ts @@ -436,7 +436,6 @@ export const PurpleTheme = { height: 36, borderRadius: 10, backgroundColor: Colors.LightPurple, - justifyContent: 'center', }, cameraFlipIcon: { width: 42, @@ -494,6 +493,10 @@ export const PurpleTheme = { paddingVertical: 9, justifyContent: 'space-between', }, + iconContainer: { + flexDirection: 'row', + alignItems: 'flex-end', + }, scannerContainer: { borderRadius: 24, alignSelf: 'center', @@ -674,24 +677,6 @@ export const PurpleTheme = { fontFamily: 'Inter_700Bold', lineHeight: 12, }, - scanLayoutHeaderContainer: { - flex: 1, - flexDirection: 'row', - marginLeft: I18nManager.isRTL ? 40 : 15, - marginTop: 15, - }, - scanLayoutHeaderTitle: { - fontSize: 26, - fontFamily: 'Inter_600SemiBold', - paddingTop: 20, - paddingBottom: 10, - }, - sendVcHeaderContainer: { - flex: 1, - flexDirection: 'row', - marginLeft: I18nManager.isRTL ? 50 : 0, - marginTop: 15, - }, }), BannerStyles: StyleSheet.create({ container: { diff --git a/routes/main.ts b/routes/main.ts index 215d1604ee..32335bb38f 100644 --- a/routes/main.ts +++ b/routes/main.ts @@ -39,12 +39,8 @@ const history: TabScreen = { component: HistoryScreen, icon: 'history', options: { - headerTitleStyle: { - fontSize: 26, - fontFamily: 'Inter_600SemiBold', - marginTop: 15, - }, title: i18n.t('MainLayout:history'), + headerRight: null, }, }; diff --git a/screens/History/HistoryScreen.tsx b/screens/History/HistoryScreen.tsx index ed6596e284..11e53943a5 100644 --- a/screens/History/HistoryScreen.tsx +++ b/screens/History/HistoryScreen.tsx @@ -5,10 +5,11 @@ import {useTranslation} from 'react-i18next'; import {Centered, Column, Text} from '../../components/ui'; import {useHistoryTab} from './HistoryScreenController'; import {ActivityLogText} from '../../components/ActivityLogText'; +import {MainRouteProps} from '../../routes/main'; import {Theme} from '../../components/ui/styleUtils'; import {BannerNotificationContainer} from '../../components/BannerNotificationContainer'; -export const HistoryScreen: React.FC = () => { +export const HistoryScreen: React.FC = () => { const {t} = useTranslation('HistoryScreen'); const controller = useHistoryTab(); diff --git a/screens/HomeScreenLayout.tsx b/screens/HomeScreenLayout.tsx index d4fd07acf7..b93c0b5979 100644 --- a/screens/HomeScreenLayout.tsx +++ b/screens/HomeScreenLayout.tsx @@ -13,7 +13,6 @@ import {SettingScreen} from './Settings/SettingScreen'; import testIDProps from '../shared/commonUtil'; import {SvgImage} from '../components/ui/svg'; import {HelpScreen} from '../components/HelpScreen'; -import {I18nManager} from 'react-native'; export const HomeScreenLayout: React.FC = props => { const {t} = useTranslation('IssuersScreen'); @@ -43,45 +42,45 @@ export const HomeScreenLayout: React.FC = props => { } }, [props.navigation, props.route]); - const screenOptions = ( - - - } - /> - - - } - navigation={props.navigation} - route={undefined} - /> - - ); const HomeScreenOptions = { - headerLeft: () => (I18nManager.isRTL ? screenOptions : SvgImage.InjiLogo()), + headerLeft: () => { + return SvgImage.InjiLogo(); + }, headerTitle: '', - headerRight: () => - I18nManager.isRTL ? SvgImage.InjiLogo() : screenOptions, + headerRight: () => ( + + + } + /> + + + } + navigation={props.navigation} + route={undefined} + /> + + ), }; return ( diff --git a/screens/MainLayout.tsx b/screens/MainLayout.tsx index 81069fe7f2..b61ed1cffb 100644 --- a/screens/MainLayout.tsx +++ b/screens/MainLayout.tsx @@ -3,11 +3,16 @@ import { BottomTabNavigationOptions, createBottomTabNavigator, } from '@react-navigation/bottom-tabs'; +import {Icon} from 'react-native-elements'; import {RequestRouteProps, RootRouteProps} from '../routes'; import {mainRoutes, share} from '../routes/main'; import {Theme} from '../components/ui/styleUtils'; import {useTranslation} from 'react-i18next'; -import {Column} from '../components/ui'; +import {Column, Row} from '../components/ui'; +import {Image} from 'react-native'; +import {SettingScreen} from './Settings/SettingScreen'; +import {HelpScreen} from '../components/HelpScreen'; + import {GlobalContext} from '../shared/GlobalContext'; import {ScanEvents} from '../machines/bleShare/scan/scanMachine'; import testIDProps from '../shared/commonUtil'; diff --git a/screens/Request/RequestLayout.tsx b/screens/Request/RequestLayout.tsx index f9709be86d..55e3cebd36 100644 --- a/screens/Request/RequestLayout.tsx +++ b/screens/Request/RequestLayout.tsx @@ -12,9 +12,6 @@ import {REQUEST_ROUTES} from '../../routes/routesConstants'; import {SquircleIconPopUpModal} from '../../components/ui/SquircleIconPopUpModal'; import {ProgressingModal} from '../../components/ProgressingModal'; import {BannerNotificationContainer} from '../../components/BannerNotificationContainer'; -import {Theme} from '../../components/ui/styleUtils'; -import {I18nManager} from 'react-native'; - const RequestStack = createNativeStackNavigator(); export const RequestLayout: React.FC = () => { @@ -44,26 +41,13 @@ export const RequestLayout: React.FC = () => { component={ReceiveVcScreen} options={{ title: t('incomingVc'), - headerLeft: () => - !I18nManager.isRTL && ( - { - controller.RESET(); - }} - style={Theme.Styles.IconContainer} - tintColor={Theme.Colors.Icon} - /> - ), - headerRight: () => - I18nManager.isRTL && ( - { - controller.RESET(); - }} - style={Theme.Styles.IconContainer} - tintColor={Theme.Colors.Icon} - /> - ), + headerLeft: () => ( + { + controller.RESET(); + }} + /> + ), }} /> )} @@ -72,26 +56,6 @@ export const RequestLayout: React.FC = () => { component={RequestScreen} options={{ title: t('receiveCard').toUpperCase(), - headerRight: () => - I18nManager.isRTL && ( - { - controller.GOTO_HOME(); - }} - style={Theme.Styles.IconContainer} - tintColor={Theme.Colors.Icon} - /> - ), - headerLeft: () => - !I18nManager.isRTL && ( - { - controller.GOTO_HOME(); - }} - style={Theme.Styles.IconContainer} - tintColor={Theme.Colors.Icon} - /> - ), }} /> diff --git a/screens/Request/RequestLayoutController.ts b/screens/Request/RequestLayoutController.ts index 68f3562b38..40cf358337 100644 --- a/screens/Request/RequestLayoutController.ts +++ b/screens/Request/RequestLayoutController.ts @@ -92,6 +92,5 @@ export function useRequestLayout() { isNavigatingToReceivedCards, DISMISS: () => requestService.send(RequestEvents.DISMISS()), RESET: () => requestService.send(RequestEvents.RESET()), - GOTO_HOME: () => navigation.navigate(BOTTOM_TAB_ROUTES.home), }; } diff --git a/screens/Scan/ScanLayout.tsx b/screens/Scan/ScanLayout.tsx index 2f28887d8e..73faf953b8 100644 --- a/screens/Scan/ScanLayout.tsx +++ b/screens/Scan/ScanLayout.tsx @@ -10,8 +10,6 @@ import {SharingSuccessModal} from './SuccessfullySharedModal'; import {Theme} from '../../components/ui/styleUtils'; import {Icon} from 'react-native-elements'; import {Loader} from '../../components/ui/Loader'; -import {Text} from '../../components/ui'; -import {I18nManager, View} from 'react-native'; const ScanStack = createNativeStackNavigator(); @@ -49,31 +47,14 @@ export const ScanLayout: React.FC = () => { component={SendVcScreen} options={{ title: t('sharingVc'), - headerTitleAlign: 'center', - headerTitle: props => ( - - - {props.children} - - - ), headerBackVisible: false, - headerRight: () => - !I18nManager.isRTL && ( - - ), - headerLeft: () => - I18nManager.isRTL && ( - - ), + headerRight: () => ( + + ), }} /> )} @@ -81,14 +62,8 @@ export const ScanLayout: React.FC = () => { name={SCAN_ROUTES.ScanScreen} component={ScanScreen} options={{ + headerTitleStyle: {fontSize: 30, fontFamily: 'Inter_600SemiBold'}, title: t('MainLayout:share'), - headerTitle: props => ( - - - {props.children} - - - ), }} /> diff --git a/screens/Scan/ScanScreen.tsx b/screens/Scan/ScanScreen.tsx index b66c99b0fd..da384c60e8 100644 --- a/screens/Scan/ScanScreen.tsx +++ b/screens/Scan/ScanScreen.tsx @@ -8,12 +8,18 @@ import {QrLogin} from '../QrLogin/QrLogin'; import {useScanScreen} from './ScanScreenController'; import BluetoothStateManager from 'react-native-bluetooth-state-manager'; import {Linking} from 'react-native'; +import {useNavigation, NavigationProp} from '@react-navigation/native'; +import {MainBottomTabParamList} from '../../routes/main'; +import {BOTTOM_TAB_ROUTES} from '../../routes/routesConstants'; import {isIOS} from '../../shared/constants'; import {BannerNotificationContainer} from '../../components/BannerNotificationContainer'; export const ScanScreen: React.FC = () => { + type ScanScreenNavigation = NavigationProp; + const {t} = useTranslation('ScanScreen'); const controller = useScanScreen(); + const navigation = useNavigation(); const [isBluetoothOn, setIsBluetoothOn] = useState(false); useEffect(() => { @@ -78,8 +84,7 @@ export const ScanScreen: React.FC = () => { ); } @@ -99,8 +104,7 @@ export const ScanScreen: React.FC = () => { ); } @@ -172,7 +176,7 @@ export const ScanScreen: React.FC = () => { } translationPath={'ScanScreen'} error="errors.storageLimitReached" - onBackdropPress={controller.GOTO_HOME} + onBackdropPress={() => navigation.navigate(BOTTOM_TAB_ROUTES.home)} /> ) ); @@ -193,7 +197,7 @@ export const ScanScreen: React.FC = () => { fill type="clear" title={t('common:cancel')} - onPress={controller.GOTO_HOME} + onPress={() => navigation.navigate(BOTTOM_TAB_ROUTES.home)} margin={[0, 8, 0, 0]} />