[Injimob 695] Show Banner message based on vc verification call response (#1408)

* [INJIMOB-695] create a enum for all the banner status types and use it in all places

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

* [INJIMOB-695] add isVerified attribute in the vcMetadata to store verification status and disable activation if verification is pending

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

* [INJIMOB-695] hide share, share with selfie and activation options in kebabe menu if verification is pending

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

* [INJIMOB-695] pass tooltip component and trigger component styles as props to custom tooltip component

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

* [INJIMOB-695] show info icon next to status in detail view and show the tool tip component when user clicks on it

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

* [INJIMOB-695] show pending icon in card and detailed view if verification is pending

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

* [INJIMOB-695] give max height to kebab menu to remove the extra space when there are few options

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

* [INJIMOB-695] rename the info icon to colored info and add black color info icon to show it in detailed view and adjust the styles of help icon in home screen

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

* [INJIMOB-695] pass the new argument to the setTextColor to set the default color to the components if wellknown is not available

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

* [INJIMOB-695] add a logic in wellknown config api method to get the fields properly from credentials supported attribute of api response based on its type

if credential supported field value is array we will use the logic as it is if it's value is of type object we will compare the credential types which we got in the wellknown api response with the credential types of the VC

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

* [INJIMOB-695] show the kebab menu icon color properly based on the position where we are showing it in ui

In detail view we are using svg image directly so no need to pass icon color and in card view if we have wellknown we will use the text color which we got in config api response otherwise we will set the default color

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

* [INJIMOB-695] add default value to the selected vc context variable in home screen machine

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

* [INJIMOB-695] add missing translations and translations for verification success and failure states

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

* [INJIMOB-695] rename verification banner info translation from verification retrigger to info in all local files

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

* [INJIMOB-695] add translation for pending status in all locale files

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

* [INJIMOB-695] adjust the styles of detailed view info icon tool tip component

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

* [INJIMOB-695] show kebab menu icon in detailed view only after getting the response from wellknown config api call and rendering the VC details

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

* [INJIMOB-695] show vc's in select vc screen in sharing flow only if they are verified by digital bazar

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

* [INJIMOB-695] adjust the styles of help icon and label in home screen

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

* [INJIMOB-695] initiate the verification call to digital bazar library and show the banner notification in detailed view based on the response

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

* [INJIMOB-695] replace setCredential action with setContext action in vcItemMachine

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

* [INJIMOB-695] handle different verification status banner scenarios in vc item and meta machines

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

* [INJIMOB-695] add translations for vc verification banner in all languages

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

* [INJIMOB-695] change the name of verification status type info to in progress in all places

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

* [INJIMOB-695] fix minor issues in verification flow

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

* [INJIMOB-695] fix some of the usecases in verification flow

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

* [INJIMOB-695] fix the styles of vc verification status in detailed view

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

* [INJIMOB-695] show the card type value in chosen language

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

* [INJIMOB-695] remove unnecessary format change in QrConsent file

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

* [INJIMOB-695] remove the banner if the verification is done and the user moves to other screen

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

* [INJIMOB-695] fix spelling mistakes and rename few variables to make them more meaningful

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

* [INJIMOB-695] change the method name from setTextColor to getTextColor and move it to vcUtils file

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

* [INJIMOB-695] change the method name from setBackgroundColor to getBackgroundColor in vcUtils file

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

* [INJIMOB-695] remove translations related to lock and revoke from all locale files

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

* [INJIMOB-695] convert detailed view status tool tip translations into object format in all local files

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

* [INJIMOB-695] chanage vcItemMachine existing state name to vcUtilitiesState

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

* [INJIMOB-695] change the name of sendVcUpdated to updateVcMetadata in vcItemMachine

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

* [INJIMOB-695] remove useBannerNotificationContainer controller file and add those events in useBannerNotification itself

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

---------

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>
This commit is contained in:
PuBHARGAVI
2024-05-08 09:19:03 +05:30
committed by GitHub
parent edd1eb6af9
commit 73630d84a0
80 changed files with 3729 additions and 2087 deletions

View File

@@ -1,8 +1,8 @@
fileignoreconfig:
- filename: package.json
checksum: 730263252adbe53cde58fb0b6988e519e766fe0f89a7b8cd261a1e5e5e598328
checksum: 2d649ba48d1bd4bc7e6c0ea7046af77f8ecce6c9117045cc7b01a98f0a44bebb
- filename: package-lock.json
checksum: 8e91542dfeba34460b4700c5b640fe6802cb1b38e1dbafd2ebcaac2fd9dbed36
checksum: a376260a2a61ed12a2d4c8a0a19dee7b4b0b293c48c5946beeae014143be9829
- filename: lib/jsonld-signatures/suites/ed255192018/ed25519.ts
checksum: 493b6e31144116cb612c24d98b97d8adcad5609c0a52c865a6847ced0a0ddc3a
- filename: components/PasscodeVerify.tsx
@@ -48,7 +48,7 @@ fileignoreconfig:
- filename: ios/fastlane/Fastfile
checksum: a4e3772dc67a07ecbcfc58be0d6d4f7fa799cec7ac25bd269ac29459c8669ca4
- filename: machines/bleShare/scan/scanMachine.ts
checksum: a514c958ca3da3c5b22a1a95ad680af8f05fb22638fab79b3842aa8fcc1b4a17
checksum: 5f4a183db610fe0ffe36e3e1129d67221535335e4a866341a5b8759228ddee15
- filename: screens/PasscodeScreen.tsx
checksum: 5d3003027b245234f8c00bfc98836f1fb90a5d9525ffacf61c53f3d50954aa6a
- filename: screens/PasscodeScreen.tsx
@@ -100,11 +100,11 @@ fileignoreconfig:
- filename: machines/settings.typegen.ts
checksum: e4ae05822f1b1c23f3f70d03dd46fd8f29ba6b52d40f2f24c121f536fbb5f2c4
- filename: .github/workflows/ui-automation.yml
checksum: 0b26a5dcb7524ba15d6aaeaf04f2ef94be9d25ef702d9072d6628bcd58e50f36
checksum: 85993a912fb873a3a2a11adde702918aedff56494e6d45c2d70f272497bf9a27
- filename: injitest/src/test/java/androidTestCases/PinVcTest.java
checksum: 6ec2787bee662ff158cbd7489d09ab131ab74484e42d7c5eba342e54898c891d
checksum: d2bb009653a57ad4ae46d2495973aa07cf64e11fd62c1d33d656cc1cdc135c93
- filename: injitest/src/test/java/androidTestCases/NoNetworkAndroidTest.java
checksum: c300122d39af06f68ecd0b6dc287daa0370fc6b744072944ddcc7fe4ded79fb3
checksum: 9d987a7422418f331960f897c1c10ca7e8209680b948eb8d7b48b0fe655e8659
- filename: injitest/src/test/java/androidTestCases/CredentialRegistryTest.java
checksum: 126ad4f513d5e417fdc3ccbace187315b8aae4399806d3259421f8bca7d41254
- filename: injitest/src/test/java/iosTestCases/NoNetworkIosTest.java
@@ -137,8 +137,6 @@ fileignoreconfig:
checksum: b735aedc84164d03c199fe89ccbf9df58f8997bfb4f60e7058a22bfe952fda3e
- filename: .github/workflows/ui-automation.yml
checksum: 0b26a5dcb7524ba15d6aaeaf04f2ef94be9d25ef702d9072d6628bcd58e50f36
- filename: components/BannerNotificationContainer.tsx
checksum: 3788503c96cbd425a253ff3f589dcc0c9e2ec4b365e9e567858c52099909f0e0
- filename: components/HelpScreen.tsx
checksum: bbc69143bd37d065bba3800396301db5a0318e8b7ba51ecd49142dda68783a01
- filename: injitest/README.md
@@ -146,7 +144,7 @@ fileignoreconfig:
- filename: shared/VCMetadata.ts
checksum: e93f988415bf91064e2cf5fbc09ff6c7226798baa5da721fa0715d5d0d6afddf
- filename: ios/Podfile.lock
checksum: c8f330a55ad911e59921215bf7d086db3dbdb5eab28202b3b450d780498ea880
checksum: 406f220cd0fd4526951b3792d1403ec0fb701fbbd22a4d887b62e90b69b1e6d0
- filename: components/BackupAndRestoreBannerNotification.tsx
checksum: e465a9947727687d784d0cb9d8db1e28f765b0659bf4a3aa6d75643aa7b14102
- filename: components/ActivityLogEvent.ts
@@ -160,7 +158,7 @@ fileignoreconfig:
- filename: machines/backupAndRestore/backup.typegen.ts
checksum: 65e671fb5a64611f00a8ca4ea0811fa0be145e8c7cc8b4fcfabbd8d882c29a96
- filename: machines/backupAndRestore/backupAndRestoreSetup.ts
checksum: 5fc57c926cf1b97bf3226ef30149d59ab3c5b437aad3315306b505dc6207d37d
checksum: 03767f9922526a765d62f8ac82a0ece12fcf7028400f64f492be6ee5daca72cd
- filename: machines/backupAndRestore/backupAndRestoreSetup.typegen.ts
checksum: b55be87b377515af3533c66ca23670c05032c3737adaaad2901f7c6d639b9519
- filename: injitest/src/main/resources/AidData.json
@@ -170,7 +168,7 @@ fileignoreconfig:
- filename: injitest/src/main/java/inji/api/ConfigManager.java
checksum: 880e066743f5979929cbfa90ef3a28bf4eb7147c9dba425b2abb035025d21aa7
- filename: injitest/src/test/java/androidTestCases/VcDownloadAndVerifyUsingEsignetTest.java
checksum: 27ed9b9c785cb9f6fd9be727696f7f3dff1e26cec262ba5582ee6734402f6a9e
checksum: 0ddae5d539e3ff6ca6a9402d8261bb6de37ae6e6f81e6b523e71496e42e8f1f9
- filename: injitest/src/test/java/androidTestCases/ChangeLanguageTest.java
checksum: c0234ddd85035f6c2cd62ba96a8a2b85da71f0752e9888130b9675bb6194bebe
- filename: ios/Inji/Inji.entitlements
@@ -236,15 +234,71 @@ fileignoreconfig:
- filename: machines/IssuersMachine.typegen.ts
checksum: 959fef1e51f0f3d5b12933f7b362e96401fb776ab12f0d13c6e542918b2ff255
- filename: screens/Home/MyVcsTab.tsx
checksum: 977ebd7c7da214f1d214cb3568ca0b1e4f2463bb932e1149e2cf6aa90f2c3f9c
- filename: machines/store.ts
checksum: 12defe49a865358a5212d03de75d13877e7c5cb75f5038c96abd3726b36c18dc
checksum: 47f9d81e69eb662b76ab12640336b6409f89058c58137a9d837e998de7c0e75f
- filename: machines/store.typegen.ts
checksum: 46f3a7c2d15ed03fc70e27ecae5a12c128011c49913b35cdb8edba12b1a999db
- filename: machines/VerifiableCredential/VCMetaMachine/VCMetaMachine.ts
checksum: c80ba680932ae3af7d1238f4db0b3f5e12c343c79335f0cd235f40068bbc03cb
checksum: 36244323200d1e965adb48205d359fba807a5a153f2fc3ce75fe34e8b1bdb01a
- filename: machines/Issuers/IssuersMachine.ts
checksum: 1eb1e912ea76c88a8d477cce9742da59b5bb41a2a39cc1dc67c5bca240c1553b
- filename: .github/scripts/set-google-clientid.sh
checksum: 013ef3b43f50ba05e18c9c83e89cc366c3f0d8ed4d931ce7daa19a757880419b
- filename: screens/Issuers/CredentialTypeSelectionScreen.tsx
checksum: 144bbf59e86a89bf580ac7931645ca3eaed69a9409de36f6ce9f88a14091a9d3
- filename: components/QrCodeOverlay.tsx
checksum: b49a3f53dd4a522f8ce47f2af72ade33e337ddbd40068911458bb3ad54197b63
- filename: machines/Issuers/IssuersEvents.ts
checksum: fd8c30e0cf43a784be883c9d79a3bff0d2bcd9075e937d225939040542998b10
- filename: machines/Issuers/IssuersGuards.ts
checksum: d87b6f4277c4be68f1884efa5c73e1b1d02a1afaefb276417b95a312f599578a
- filename: machines/Issuers/IssuersActions.ts
checksum: 63cbedfbedbe3ef7d5553e44df04d105a8b171d23bf46d1d85daff45e54bcf78
- filename: injitest/automation_trigger.sh
checksum: f2f34839c99cb1b871dde17aed8508a071345d22738796e005ff709d2dab8644
- filename: machines/Issuers/IssuersService.ts
checksum: ee7622a03c23705b4c4dea218ccbe6504a51a5a68170a9059a2cde3b4c6a9984
- filename: screens/Home/ViewVcModal.tsx
checksum: 128176a2551fe256378eb88a3d962dd82bbaab44b5f986784de40bf1183f0145
- filename: injitest/src/main/resources/TestData.json
checksum: 1b5af14c96b456898259b4cb7a5607b006404cf0360274bdc204d7d065698e3c
- filename: injitest/src/test/java/androidTestCases/ActivateVcTest.java
checksum: c79ebcc903fda178b19b7476e4801c228cdb2cdb6f52bf0b6b5d81ca475bffb9
- filename: machines/VerifiableCredential/VCMetaMachine/VCMetaActions.ts
checksum: f7f2afe0ba50449a8cf2b7eef87b18082ab1cb0db287e198a709082046e5cb08
checksum: 6c1f69f90102e57d1c08816b2bedadaa0ee95e0c7f9b1bc124cccc66ffb69fa2
- filename: injitest/src/test/java/androidTestCases/DeletingVcTest.java
checksum: 6f95a4046eb7959ffccbc530936dd6ab14aad425b934e7bf3b65f0308ae07ff0
- filename: injitest/src/test/java/androidTestCases/GenerateUinOrVidTest.java
checksum: 677876a830862d779290d3272c4ad3bfdeb8d4f4c9899a6cdea5ceb7e52e1616
- filename: machines/VerifiableCredential/VCMetaMachine/VCMetaSelectors.ts
checksum: 648bf8c8cef0477f31b2a3f2b916a530cb55cf961dafa7c48992d70d7eb2b821
checksum: 5f89d24401e6345fd402c7f523f23d567031a571d4b04e1c993c091fa47dc781
- filename: injitest/src/test/java/androidTestCases/UnlockWithPasscodeTest.java
checksum: efe21ba6b9e1b760cee02f0d6c5c776722142feeff7417cfdb7536ab80be3476
- filename: injitest/src/test/java/androidTestCases/VerifyHistoryTest.java
checksum: ebd8683aed0b7b9be50ed8f900896557623c366c68b98bde392ea1a343edeafb
- filename: injitest/src/test/java/androidTestCases/VcDownloadAndVerifyUsingUinTest.java
checksum: ca06dd901386edcd914bd39b301629589d82269b79e80fad5e3562968532b590
- filename: machines/bleShare/scan/scanGuards.ts
checksum: a26a4100b857313e35a1c70604923fa2670f38440b10f089755fb1a1f45f6859
- filename: machines/QrLogin/QrLoginMachine.ts
checksum: f4234549baea9a7f69be98f52c30a04f2f6138f9b1f2b60a7b40f15f7e03345b
- filename: machines/QrLogin/QrLoginServices.ts
checksum: b20d0caa6d23078b4010ea5185f01270356422dd216edd7834b069cdedd3383d
- filename: machines/bleShare/scan/scanActions.ts
checksum: 1be68caa29937d5f724fc45f8164ee607e556aae008c00ac89b83968030ed7ed
- filename: injitest/src/test/java/iosTestCases/ActivateVcTest.java
checksum: 2adfd7c38a3302ab8ae091417eb9af15235406c7fb2c6399f6421bcf89612a5a
- filename: injitest/src/test/java/iosTestCases/GenerateUinOrVidTest.java
checksum: a56bcafd022bc740bd17e657c578b7559fda30c84d80eb69060624009e5b021b
- filename: injitest/src/test/java/iosTestCases/VerifyHistoryTest.java
checksum: f5af73c269d0de91814dc77e270b08fadc44d8daf41f66d4b749bc0fc8793993
- filename: machines/store.ts
checksum: fa2330002fc3f638a09a816a37a8ef26268ae6ab65c23aacee846244ebb1cb4e
- filename: components/BannerNotificationContainer.tsx
checksum: e2c31bb25ebe1234369c7dc577fa3657b03c3a0bf561cd6fd5eb9e0919160cb1
- filename: injitest/src/test/java/iosTestCases/PinVcTest.java
checksum: 435d345931e2d14dad99faafdf0d79fad025c049252ea94bca57dd6608d69c4c
- filename: injitest/src/test/java/androidTestCases/VcBackupAndRestoreTest.java
checksum: 8713672812eb3f737243c0d431574a84766559a336754bc53c9c5bfbd006707d
- filename: machines/VerifiableCredential/VCItemMachine/VCItemMachine.typegen.ts
checksum: 8ac74d2e5c6de179e460b86899eb048ad4c5bd67abc3d28c015e92335b8afe24
version: ""

9
assets/Colored_Info.svg Normal file
View File

@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16.001" height="16.001" viewBox="0 0 16.001 16.001">
<defs>
<linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="0.942" gradientUnits="objectBoundingBox">
<stop offset="0" stop-color="#f59b4b"/>
<stop offset="1" stop-color="#e86e04"/>
</linearGradient>
</defs>
<path id="info_FILL0_wght400_GRAD0_opsz48" d="M87.46-868h1.2v-4.8h-1.2Zm.54-6.28a.65.65,0,0,0,.47-.184.609.609,0,0,0,.19-.456.669.669,0,0,0-.19-.484.628.628,0,0,0-.47-.2.63.63,0,0,0-.47.2.668.668,0,0,0-.19.484.61.61,0,0,0,.19.456A.649.649,0,0,0,88-874.28ZM88.006-864a7.744,7.744,0,0,1-3.11-.63,8.129,8.129,0,0,1-2.545-1.72,8.125,8.125,0,0,1-1.72-2.547,7.759,7.759,0,0,1-.63-3.113,7.758,7.758,0,0,1,.63-3.113,8.006,8.006,0,0,1,1.72-2.537,8.213,8.213,0,0,1,2.547-1.71A7.758,7.758,0,0,1,88.01-880a7.759,7.759,0,0,1,3.113.63,8.091,8.091,0,0,1,2.537,1.71,8.08,8.08,0,0,1,1.71,2.54A7.777,7.777,0,0,1,96-872a7.744,7.744,0,0,1-.63,3.11,8.172,8.172,0,0,1-1.71,2.542,8.077,8.077,0,0,1-2.54,1.72A7.738,7.738,0,0,1,88.006-864Zm0-1.2a6.532,6.532,0,0,0,4.81-1.99,6.582,6.582,0,0,0,1.98-4.82,6.555,6.555,0,0,0-1.976-4.81A6.557,6.557,0,0,0,88-878.8a6.576,6.576,0,0,0-4.81,1.976A6.54,6.54,0,0,0,81.2-872a6.554,6.554,0,0,0,1.99,4.81A6.565,6.565,0,0,0,88.01-865.2ZM88-872Z" transform="translate(-80 880)" fill="url(#linear-gradient)"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,9 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16.001" height="16.001" viewBox="0 0 16.001 16.001">
<defs>
<linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="0.942" gradientUnits="objectBoundingBox">
<stop offset="0" stop-color="#f59b4b"/>
<stop offset="1" stop-color="#e86e04"/>
</linearGradient>
</defs>
<path id="info_FILL0_wght400_GRAD0_opsz48" d="M87.46-868h1.2v-4.8h-1.2Zm.54-6.28a.65.65,0,0,0,.47-.184.609.609,0,0,0,.19-.456.669.669,0,0,0-.19-.484.628.628,0,0,0-.47-.2.63.63,0,0,0-.47.2.668.668,0,0,0-.19.484.61.61,0,0,0,.19.456A.649.649,0,0,0,88-874.28ZM88.006-864a7.744,7.744,0,0,1-3.11-.63,8.129,8.129,0,0,1-2.545-1.72,8.125,8.125,0,0,1-1.72-2.547,7.759,7.759,0,0,1-.63-3.113,7.758,7.758,0,0,1,.63-3.113,8.006,8.006,0,0,1,1.72-2.537,8.213,8.213,0,0,1,2.547-1.71A7.758,7.758,0,0,1,88.01-880a7.759,7.759,0,0,1,3.113.63,8.091,8.091,0,0,1,2.537,1.71,8.08,8.08,0,0,1,1.71,2.54A7.777,7.777,0,0,1,96-872a7.744,7.744,0,0,1-.63,3.11,8.172,8.172,0,0,1-1.71,2.542,8.077,8.077,0,0,1-2.54,1.72A7.738,7.738,0,0,1,88.006-864Zm0-1.2a6.532,6.532,0,0,0,4.81-1.99,6.582,6.582,0,0,0,1.98-4.82,6.555,6.555,0,0,0-1.976-4.81A6.557,6.557,0,0,0,88-878.8a6.576,6.576,0,0,0-4.81,1.976A6.54,6.54,0,0,0,81.2-872a6.554,6.554,0,0,0,1.99,4.81A6.565,6.565,0,0,0,88.01-865.2ZM88-872Z" transform="translate(-80 880)" fill="url(#linear-gradient)"/>
<svg id="Info_Icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path id="Path_155580" data-name="Path 155580" d="M0,0H16V16H0Z" fill="none"/>
<path id="Path_155581" data-name="Path 155581" d="M7.4,5H8.6V6.2H7.4Zm0,2.4H8.6V11H7.4ZM8,2a6,6,0,1,0,6,6A6,6,0,0,0,8,2ZM8,12.8A4.8,4.8,0,1,1,12.8,8,4.806,4.806,0,0,1,8,12.8Z" fill="#666"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 379 B

View File

@@ -3,11 +3,7 @@ import {useBackupScreen} from '../screens/backupAndRestore/BackupController';
import {BannerNotification} from './BannerNotification';
import {useTranslation} from 'react-i18next';
import {useBackupRestoreScreen} from '../screens/Settings/BackupRestoreController';
import {
BANNER_TYPE_SUCCESS,
BANNER_TYPE_ERROR,
BANNER_TYPE_INFO,
} from '../shared/constants';
import {BannerStatusType} from './BannerNotification';
export const BackupAndRestoreBannerNotification: React.FC = () => {
const backUpController = useBackupScreen();
@@ -22,7 +18,7 @@ export const BackupAndRestoreBannerNotification: React.FC = () => {
return (
<BannerNotification
type={BANNER_TYPE_ERROR}
type={BannerStatusType.ERROR}
message={translation}
onClosePress={backUpController.DISMISS}
key={`backupFailure-${backUpController.backupErrorReason}Popup`}
@@ -38,7 +34,7 @@ export const BackupAndRestoreBannerNotification: React.FC = () => {
return (
<BannerNotification
type={BANNER_TYPE_ERROR}
type={BannerStatusType.ERROR}
key={`restoreFailure-${restoreController.restoreErrorReason}Popup`}
message={translation}
onClosePress={restoreController.DISMISS}
@@ -51,7 +47,7 @@ export const BackupAndRestoreBannerNotification: React.FC = () => {
<>
{backUpController.showBackupInProgress && (
<BannerNotification
type={BANNER_TYPE_INFO}
type={BannerStatusType.IN_PROGRESS}
message={t('backupInProgress')}
onClosePress={backUpController.DISMISS_SHOW_BACKUP_IN_PROGRESS}
key={'dataBackupInProgress'}
@@ -61,7 +57,7 @@ export const BackupAndRestoreBannerNotification: React.FC = () => {
{backUpController.isBackingUpSuccess && (
<BannerNotification
type={BANNER_TYPE_SUCCESS}
type={BannerStatusType.SUCCESS}
message={t('backupSuccessful')}
onClosePress={backUpController.DISMISS}
key={'dataBackupSuccessPopup'}
@@ -73,7 +69,7 @@ export const BackupAndRestoreBannerNotification: React.FC = () => {
{restoreController.showRestoreInProgress && (
<BannerNotification
type={BANNER_TYPE_INFO}
type={BannerStatusType.IN_PROGRESS}
message={t('restoreInProgress')}
onClosePress={restoreController.DISMISS_SHOW_RESTORE_IN_PROGRESS}
key={'restoreInProgress'}
@@ -83,7 +79,7 @@ export const BackupAndRestoreBannerNotification: React.FC = () => {
{restoreController.isBackUpRestoreSuccess && (
<BannerNotification
type={BANNER_TYPE_SUCCESS}
type={BannerStatusType.SUCCESS}
message={t('restoreSuccessful')}
onClosePress={restoreController.DISMISS}
key={'restoreBackupSuccessPopup'}

View File

@@ -4,11 +4,6 @@ import {Column, Row, Text} from './ui';
import {Theme} from './ui/styleUtils';
import {Icon} from 'react-native-elements';
import testIDProps from '../shared/commonUtil';
import {
BANNER_TYPE_SUCCESS,
BANNER_TYPE_ERROR,
BANNER_TYPE_INFO,
} from '../shared/constants';
export const BannerNotification: React.FC<BannerNotificationProps> = props => {
return (
@@ -37,12 +32,20 @@ export const BannerNotification: React.FC<BannerNotificationProps> = props => {
);
};
export enum BannerStatusType {
IN_PROGRESS = 'inProgress',
SUCCESS = 'success',
ERROR = 'error',
}
export type BannerStatus =
| BannerStatusType.IN_PROGRESS
| BannerStatusType.SUCCESS
| BannerStatusType.ERROR;
export interface BannerNotificationProps {
message: string;
onClosePress: () => void;
testId: string;
type:
| typeof BANNER_TYPE_SUCCESS
| typeof BANNER_TYPE_ERROR
| typeof BANNER_TYPE_INFO;
type: BannerStatusType;
}

View File

@@ -1,24 +1,28 @@
import React from 'react';
import {View} from 'react-native';
import {BannerNotification} from './BannerNotification';
import {UseWalletBindingSuccess} from './WalletBindingSuccessController';
import {
BannerNotification,
BannerStatus,
BannerStatusType,
} from './BannerNotification';
import {BackupAndRestoreBannerNotification} from './BackupAndRestoreBannerNotification';
import {UseBannerNotification} from './BannerNotificationController';
import {useTranslation} from 'react-i18next';
import {BANNER_TYPE_ERROR, BANNER_TYPE_SUCCESS} from '../shared/constants';
import {useScanScreen} from '../screens/Scan/ScanScreenController';
import {Theme} from './ui/styleUtils';
export const BannerNotificationContainer: React.FC = () => {
const WalletBindingController = UseWalletBindingSuccess();
const WalletBindingSuccess = WalletBindingController.isBindingSuccess;
export const BannerNotificationContainer: React.FC<
BannerNotificationContainerProps
> = ({showVerificationStatusBanner = true}) => {
const scanScreenController = useScanScreen();
const showQuickShareSuccessBanner =
scanScreenController.showQuickShareSuccessBanner;
const bannerNotificationController = UseBannerNotification();
const WalletBindingSuccess = bannerNotificationController.isBindingSuccess;
const {t} = useTranslation('BannerNotification');
const rt = useTranslation('RequestScreen').t;
const verificationStatus = bannerNotificationController.verificationStatus;
return (
<>
@@ -27,9 +31,11 @@ export const BannerNotificationContainer: React.FC = () => {
{WalletBindingSuccess && (
<View style={Theme.BannerStyles.topBanner}>
<BannerNotification
type={BANNER_TYPE_SUCCESS}
type={BannerStatusType.SUCCESS}
message={t('activated')}
onClosePress={WalletBindingController.DISMISS}
onClosePress={
bannerNotificationController.RESET_WALLET_BINDING_SUCCESS
}
key={'activatedVcPopup'}
testId={'activatedVcPopup'}
/>
@@ -39,7 +45,7 @@ export const BannerNotificationContainer: React.FC = () => {
{showQuickShareSuccessBanner && (
<View style={Theme.BannerStyles.topBanner}>
<BannerNotification
type={BANNER_TYPE_SUCCESS}
type={BannerStatusType.SUCCESS}
message={rt('status.accepted.message')}
onClosePress={scanScreenController.DISMISS_QUICK_SHARE_BANNER}
key={'quickShareSuccessBanner'}
@@ -50,7 +56,7 @@ export const BannerNotificationContainer: React.FC = () => {
{bannerNotificationController.isPasscodeUnlock && (
<BannerNotification
type="success"
type={BannerStatusType.SUCCESS}
message={t('alternatePasscodeSuccess')}
onClosePress={bannerNotificationController.DISMISS}
testId={'alternatePasscodeSuccess'}
@@ -60,16 +66,31 @@ export const BannerNotificationContainer: React.FC = () => {
{bannerNotificationController.isBiometricUnlock && (
<BannerNotification
type="success"
type={BannerStatusType.SUCCESS}
message={t('alternateBiometricSuccess')}
onClosePress={bannerNotificationController.DISMISS}
testId={'alternateBiometricSuccess'}
key={'updateBiometric'}
/>
)}
{verificationStatus !== null && showVerificationStatusBanner && (
<BannerNotification
type={verificationStatus.statusType}
message={t(`VcVerificationBanner:${verificationStatus?.statusType}`, {
vcDetails: `${t(`VcDetails:${verificationStatus.vcType}`)} ${
verificationStatus.vcNumber
}`,
})}
onClosePress={bannerNotificationController.RESET_VERIFICATION_STATUS}
key={'reVerificationInProgress'}
testId={'reVerificationInProgress'}
/>
)}
{bannerNotificationController.isDownloadingFailed && (
<BannerNotification
type={BANNER_TYPE_ERROR}
type={BannerStatusType.ERROR}
message={t('MyVcsTab:downloadingVcFailed')}
onClosePress={bannerNotificationController.RESET_DOWNLOADING_FAILED}
key={'downloadingVcFailedPopup'}
@@ -79,3 +100,13 @@ export const BannerNotificationContainer: React.FC = () => {
</>
);
};
export type vcVerificationBannerDetails = {
statusType: BannerStatus;
vcType: string;
vcNumber: string;
};
export interface BannerNotificationContainerProps {
showVerificationStatusBanner?: boolean;
}

View File

@@ -8,13 +8,19 @@ import {useContext} from 'react';
import {GlobalContext} from '../shared/GlobalContext';
import {VcMetaEvents} from '../machines/VerifiableCredential/VCMetaMachine/VCMetaMachine';
import {selectIsDownloadingFailed} from '../machines/VerifiableCredential/VCMetaMachine/VCMetaSelectors';
import {
selectVerificationStatus,
selectWalletBindingSuccess,
} from '../machines/VerifiableCredential/VCItemMachine/VCItemSelectors';
export const UseBannerNotification = () => {
const {appService} = useContext(GlobalContext);
const settingsService = appService.children.get('settings');
const settingsService = appService.children.get('settings')!!;
const vcMetaService = appService.children.get('vcMeta')!!;
return {
isBindingSuccess: useSelector(vcMetaService, selectWalletBindingSuccess),
verificationStatus: useSelector(vcMetaService, selectVerificationStatus),
isPasscodeUnlock: useSelector(settingsService, selectIsPasscodeUnlock),
isBiometricUnlock: useSelector(settingsService, selectIsBiometricUnlock),
@@ -22,8 +28,12 @@ export const UseBannerNotification = () => {
DISMISS: () => {
settingsService.send(SettingsEvents.DISMISS());
},
RESET_WALLET_BINDING_SUCCESS: () =>
vcMetaService.send(VcMetaEvents.RESET_WALLET_BINDING_SUCCESS()),
RESET_VERIFICATION_STATUS: () =>
vcMetaService.send(VcMetaEvents.RESET_VERIFICATION_STATUS(null)),
RESET_DOWNLOADING_FAILED: () => {
vcMetaService?.send(VcMetaEvents.RESET_DOWNLOADING_FAILED());
vcMetaService.send(VcMetaEvents.RESET_DOWNLOADING_FAILED());
},
};
};

View File

@@ -26,7 +26,7 @@ export const KebabPopUp: React.FC<KebabPopUpProps> = props => {
accessible={true}
name={props.iconName}
type={props.iconType}
{...(props.iconColor ? props.iconColor : Theme.Colors.helpText)}
color={props.iconColor}
size={Theme.ICON_SMALL_SIZE}
/>
)}
@@ -85,7 +85,7 @@ export interface KebabPopUpProps {
isVisible?: boolean;
onDismiss: () => void;
service: ActorRefFrom<typeof VCItemMachine>;
iconColor?: any;
iconColor?: string;
icon?: any;
vcHasImage: boolean;
}

View File

@@ -0,0 +1,21 @@
import React from 'react';
import {View} from 'react-native';
import {Icon} from 'react-native-elements';
import {Theme} from './ui/styleUtils';
const PendingIcon: React.FC = () => {
return (
<View style={Theme.Styles.verificationStatusIconContainer}>
<View style={Theme.Styles.verificationStatusIconInner}>
<Icon
name="alert-circle"
type="material-community"
color={Theme.Colors.PendingIcon}
size={12}
/>
</View>
</View>
);
};
export default PendingIcon;

View File

@@ -87,7 +87,7 @@ export const VCCardView: React.FC<VCItemProps> = props => {
isKebabPopUp={isKebabPopUp}
DISMISS={DISMISS}
KEBAB_POPUP={KEBAB_POPUP}
isVerified={credential !== null}
isVerified={props.vcMetadata.isVerified}
/>
</Pressable>
<ErrorMessageOverlay

View File

@@ -9,14 +9,15 @@ import {Theme} from '../../ui/styleUtils';
import {CheckBox, Icon} from 'react-native-elements';
import {SvgImage} from '../../ui/svg';
import {VcItemContainerProfileImage} from '../../VcItemContainerProfileImage';
import {isVCLoaded, setBackgroundColour} from '../common/VCUtils';
import {setTextColor, VCItemFieldValue} from '../common/VCItemField';
import {isVCLoaded, getBackgroundColour} from '../common/VCUtils';
import {VCItemFieldValue} from '../common/VCItemField';
import {WalletBinding} from '../../../screens/Home/MyVcs/WalletBinding';
import {VCVerification} from '../../VCVerification';
import {Issuers} from '../../../shared/openId4VCI/Utils';
import {VCItemContainerFlowType} from '../../../shared/Utils';
import {RemoveVcWarningOverlay} from '../../../screens/Home/MyVcs/RemoveVcWarningOverlay';
import {HistoryTab} from '../../../screens/Home/MyVcs/HistoryTab';
import {getTextColor} from '../common/VCUtils';
export const VCCardViewContent: React.FC<VCItemContentProps> = props => {
const isVCSelectable = props.selectable && (
@@ -43,7 +44,7 @@ export const VCCardViewContent: React.FC<VCItemContentProps> = props => {
resizeMode="stretch"
style={[
Theme.Styles.backgroundImageContainer,
setBackgroundColour(props.wellknown),
getBackgroundColour(props.wellknown),
]}>
<Column>
<Row crossAlign="center" padding="3 0 0 3">
@@ -86,7 +87,10 @@ export const VCCardViewContent: React.FC<VCItemContentProps> = props => {
accessible={false}
style={Theme.Styles.kebabPressableContainer}>
<KebabPopUp
iconColor={setTextColor(props.wellknown)}
iconColor={getTextColor(
props.wellknown,
Theme.Colors.helpText,
)}
vcMetadata={props.vcMetadata}
iconName="dots-three-horizontal"
iconType="entypo"

View File

@@ -1,4 +1,4 @@
import React, {useEffect, useState} from 'react';
import React from 'react';
import {useTranslation} from 'react-i18next';
import {Image, ImageBackground, View} from 'react-native';
import {
@@ -9,20 +9,14 @@ import {Button, Column, Row, Text} from '../../ui';
import {Theme} from '../../ui/styleUtils';
import {QrCodeOverlay} from '../../QrCodeOverlay';
import {SvgImage} from '../../ui/svg';
import {
getDetailedViewFields,
isActivationNeeded,
} from '../../../shared/openId4VCI/Utils';
import {isActivationNeeded} from '../../../shared/openId4VCI/Utils';
import {
BOTTOM_SECTION_FIELDS_WITH_DETAILED_ADDRESS_FIELDS,
DETAIL_VIEW_BOTTOM_SECTION_FIELDS,
DETAIL_VIEW_DEFAULT_FIELDS,
fieldItemIterator,
isVCLoaded,
setBackgroundColour,
getBackgroundColour,
getTextColor,
} from '../common/VCUtils';
import {setTextColor} from '../common/VCItemField';
import {ActivityIndicator} from '../../ui/ActivityIndicator';
import {ProfileIcon} from '../../ProfileIcon';
const getProfileImage = (face: any) => {
@@ -44,20 +38,6 @@ export const VCDetailView: React.FC<VCItemDetailsProps> = props => {
const logo = props.verifiableCredentialData.issuerLogo;
const face = props.verifiableCredentialData.face;
const verifiableCredential = props.credential;
let [fields, setFields] = useState([]);
const [wellknown, setWellknown] = useState(null);
useEffect(() => {
getDetailedViewFields(
props.verifiableCredentialData?.issuer,
props.verifiableCredentialData?.wellKnown,
props.verifiableCredentialData?.credentialTypes,
DETAIL_VIEW_DEFAULT_FIELDS,
).then(response => {
setWellknown(response.wellknown);
setFields(response.fields);
});
}, [props.verifiableCredentialData?.wellKnown]);
const shouldShowHrLine = verifiableCredential => {
const availableFieldNames = Object.keys(
@@ -75,10 +55,6 @@ export const VCDetailView: React.FC<VCItemDetailsProps> = props => {
return false;
};
if (!isVCLoaded(verifiableCredential, fields)) {
return <ActivityIndicator />;
}
return (
<>
<Column scroll>
@@ -92,7 +68,7 @@ export const VCDetailView: React.FC<VCItemDetailsProps> = props => {
resizeMode="stretch"
style={[
Theme.Styles.openCardBgContainer,
setBackgroundColour(wellknown),
getBackgroundColour(props.wellknown),
]}
source={Theme.OpenCard}>
<Row padding="14 14 0 14" margin="0 0 0 0">
@@ -121,9 +97,9 @@ export const VCDetailView: React.FC<VCItemDetailsProps> = props => {
margin={'0 0 0 24'}
style={{flex: 1}}>
{fieldItemIterator(
fields,
props.fields,
verifiableCredential,
wellknown,
props.wellknown,
props,
)}
</Column>
@@ -134,15 +110,17 @@ export const VCDetailView: React.FC<VCItemDetailsProps> = props => {
style={[
Theme.Styles.hrLine,
{
borderBottomColor: setTextColor(wellknown, 'hrLine')
?.color,
borderBottomColor: getTextColor(
props.wellknown,
Theme.Styles.hrLine.borderBottomColor,
),
},
]}></View>
<Column padding="0 14 14 14">
{fieldItemIterator(
DETAIL_VIEW_BOTTOM_SECTION_FIELDS,
verifiableCredential,
wellknown,
props.wellknown,
props,
)}
</Column>
@@ -198,6 +176,9 @@ export const VCDetailView: React.FC<VCItemDetailsProps> = props => {
onPress={props.onBinding}
type="gradient"
size="Large"
disabled={
!props.verifiableCredentialData.vcMetadata.isVerified
}
/>
</Column>
) : (
@@ -234,6 +215,8 @@ export const VCDetailView: React.FC<VCItemDetailsProps> = props => {
};
export interface VCItemDetailsProps {
fields: any[];
wellknown: any;
credential: VerifiableCredential | Credential;
verifiableCredentialData: any;
walletBindingResponse: WalletBindingResponse;

View File

@@ -1,19 +1,65 @@
import {Column, Text} from '../../ui';
import {Dimensions, View} from 'react-native';
import {Column, Row, Text} from '../../ui';
import {CustomTooltip} from '../../ui/ToolTip';
import {Theme} from '../../ui/styleUtils';
import React from 'react';
import {SvgImage} from '../../ui/svg';
import {useTranslation} from 'react-i18next';
import {getTextColor} from './VCUtils';
export const VCItemFieldName = ({fieldName, wellknown, testID}) => {
const {t} = useTranslation('ViewVcModal');
return (
<>
<Row>
{fieldName && (
<Text
testID={`${testID}Title`}
{...setTextColor(wellknown)}
color={getTextColor(wellknown, Theme.Colors.DetailsLabel)}
style={Theme.Styles.fieldItemTitle}>
{fieldName}
</Text>
)}
</>
{fieldName == t('VcDetails:status') && (
<CustomTooltip
testID="statusToolTip"
width={Dimensions.get('screen').width * 0.8}
height={Dimensions.get('screen').height * 0.18}
triggerComponent={SvgImage.info()}
triggerComponentStyles={{marginLeft: 2, marginTop: 2}}
toolTipContent={
<Column align="flex-start">
<View style={{marginBottom: 20}}>
<Text weight="semibold">
{t('statusToolTipContent.valid.title')}
</Text>
<Text
weight="regular"
style={[
Theme.Styles.tooltipContentDescription,
{marginTop: 3},
]}>
{t('statusToolTipContent.valid.description')}
</Text>
</View>
<View>
<Text weight="semibold">
{t('statusToolTipContent.pending.title')}
</Text>
<Text
weight="regular"
style={[
Theme.Styles.tooltipContentDescription,
{marginTop: 3},
]}>
{t('statusToolTipContent.pending.description')}
</Text>
</View>
</Column>
}
/>
)}
</Row>
);
};
@@ -22,7 +68,7 @@ export const VCItemFieldValue = ({fieldValue, wellknown, testID}) => {
<>
<Text
testID={`${testID}Value`}
{...setTextColor(wellknown)}
color={getTextColor(wellknown, Theme.Colors.Details)}
style={Theme.Styles.fieldItemValue}>
{fieldValue}
</Text>
@@ -38,15 +84,3 @@ export const VCItemField = props => {
</Column>
);
};
export const setTextColor = (wellknown: any, component = '') => {
if (wellknown && wellknown?.credentials_supported[0]?.display) {
return {
color: wellknown.credentials_supported[0]?.display[0]?.text_color
? wellknown.credentials_supported[0].display[0].text_color
: component === 'hrLine'
? Theme.Styles.hrLine.borderBottomColor
: Theme.Colors.Details,
};
}
};

View File

@@ -11,6 +11,7 @@ import {CREDENTIAL_REGISTRY_EDIT} from 'react-native-dotenv';
import {getIDType} from '../../../shared/openId4VCI/Utils';
import {VCVerification} from '../../VCVerification';
import {MIMOTO_BASE_URL} from '../../../shared/constants';
import {useTranslation} from 'react-i18next';
export const CARD_VIEW_DEFAULT_FIELDS = ['fullName'];
export const DETAIL_VIEW_DEFAULT_FIELDS = [
@@ -50,6 +51,7 @@ export const getFieldValue = (
wellknown: any,
props: any,
) => {
const {t} = useTranslation();
const date = new Date(
getLocalizedField(verifiableCredential?.credentialSubject[field]),
).toString();
@@ -61,11 +63,11 @@ export const getFieldValue = (
return (
<VCVerification
wellknown={wellknown}
isVerified={props.credential !== null}
isVerified={props.verifiableCredentialData.vcMetadata.isVerified}
/>
);
case 'idType':
return getIDType(verifiableCredential);
return t(`VcDetails:${getIDType(verifiableCredential)}`);
case 'credentialRegistry':
return props?.vc?.credentialRegistry;
case 'address':
@@ -82,11 +84,44 @@ export const getFieldValue = (
}
};
export const getFieldName = (field: string, wellknown: any) => {
export const getCredentialDefinition = (
wellknown: any,
vcCredentialTypes: Object[],
) => {
if (Array.isArray(wellknown.credentials_supported)) {
return wellknown.credentials_supported[0].credential_definition;
} else {
for (const supportedCredential in wellknown.credentials_supported) {
const credentialDefinition =
wellknown.credentials_supported[supportedCredential]
.credential_definition;
if (
JSON.stringify(credentialDefinition.type) ===
JSON.stringify(vcCredentialTypes)
) {
return credentialDefinition;
}
}
return null;
}
};
export const getFieldName = (
field: string,
wellknown: any,
vcCredentialTypes: Object[],
) => {
if (wellknown && wellknown.credentials_supported) {
const fieldObj =
wellknown.credentials_supported[0].credential_definition
.credentialSubject[field];
const credentialDefinition = getCredentialDefinition(
wellknown,
vcCredentialTypes,
);
if (!credentialDefinition) {
console.error(
'Credential definition is not available for the selected credential type',
);
}
let fieldObj = credentialDefinition.credentialSubject[field];
if (fieldObj) {
const newFieldObj = fieldObj.display.map(obj => {
return {language: obj.locale, value: obj.name};
@@ -97,7 +132,7 @@ export const getFieldName = (field: string, wellknown: any) => {
return i18n.t(`VcDetails:${field}`);
};
export const setBackgroundColour = (wellknown: any) => {
export const getBackgroundColour = (wellknown: any) => {
if (wellknown && wellknown.credentials_supported[0]?.display) {
return {
backgroundColor: wellknown.credentials_supported[0].display[0]
@@ -108,6 +143,12 @@ export const setBackgroundColour = (wellknown: any) => {
}
};
export const getTextColor = (wellknown: any, defaultColor: string) => {
return (
wellknown?.credentials_supported[0]?.display[0]?.text_color ?? defaultColor
);
};
export function getAddressFields() {
return [
'addressLine1',
@@ -148,7 +189,11 @@ export const fieldItemIterator = (
props: any,
) => {
return fields.map(field => {
const fieldName = getFieldName(field, wellknown);
const fieldName = getFieldName(
field,
wellknown,
props.verifiableCredentialData.vcCredentialTypes,
);
const fieldValue = getFieldValue(
verifiableCredential,
field,

View File

@@ -1,36 +1,34 @@
import testIDProps from '../shared/commonUtil';
import {setTextColor} from './VC/common/VCItemField';
import {getTextColor} from './VC/common/VCUtils';
import VerifiedIcon from './VerifiedIcon';
import {Row, Text} from './ui';
import {Theme} from './ui/styleUtils';
import React from 'react';
import {useTranslation} from 'react-i18next';
import PendingIcon from './PendingIcon';
export const VCVerification: React.FC = ({wellknown, isVerified}: any) => {
const {t} = useTranslation('VcDetails');
const statusText = isVerified ? t('valid') : t('pending');
const statusIcon = isVerified ? <VerifiedIcon /> : <PendingIcon />;
return (
<Row
{...testIDProps('verified')}
style={{
justifyContent: 'space-between',
alignItems: 'center',
}}>
{/* TODO - Handle VC Verification pending status as part of 695 */}
{isVerified && (
<React.Fragment>
<VerifiedIcon />
<Text
testID="verificationStatus"
color={Theme.Colors.Details}
style={[
Theme.Styles.detailsValue,
setTextColor(wellknown),
{fontFamily: 'Inter_600SemiBold'},
]}>
{t('valid')}
</Text>
</React.Fragment>
)}
<React.Fragment>
{statusIcon}
<Text
testID="verificationStatus"
color={getTextColor(wellknown, Theme.Colors.Details)}
style={[
Theme.Styles.detailsValue,
{fontFamily: 'Inter_600SemiBold'},
]}>
{statusText}
</Text>
</React.Fragment>
</Row>
);
};

View File

@@ -5,8 +5,8 @@ import {Theme} from './ui/styleUtils';
const VerifiedIcon: React.FC = () => {
return (
<View style={Theme.Styles.verifiedIconContainer}>
<View style={Theme.Styles.verifiedIconInner}>
<View style={Theme.Styles.verificationStatusIconContainer}>
<View style={Theme.Styles.verificationStatusIconInner}>
<Icon
testID="statusIcon"
name="check-circle"

View File

@@ -1,21 +0,0 @@
import {useContext} from 'react';
import {GlobalContext} from '../shared/GlobalContext';
import {useSelector} from '@xstate/react';
import {selectWalletBindingSuccess} from '../machines/VerifiableCredential/VCMetaMachine/VCMetaSelectors';
import {VcMetaEvents} from '../machines/VerifiableCredential/VCMetaMachine/VCMetaMachine';
export const UseWalletBindingSuccess = () => {
const {appService} = useContext(GlobalContext);
const vcMetaService = appService.children.get('vcMeta')!!;
const isBindingSuccess = useSelector(
vcMetaService,
selectWalletBindingSuccess,
);
const DISMISS = () => {
vcMetaService?.send(VcMetaEvents.RESET_WALLET_BINDING_SUCCESS());
};
return {
isBindingSuccess,
DISMISS,
};
};

View File

@@ -25,12 +25,6 @@ export const getKebabMenuOptions = props => {
onPress: controller.PIN_CARD,
testID: 'pinOrUnPinCard',
},
{
label: t('share'),
icon: SvgImage.OutlinedShareIcon(),
onPress: loadScanScreen(VCShareFlowType.MINI_VIEW_SHARE),
testID: 'shareVcFromKebab',
},
{
label: t('viewActivityLog'),
icon: SvgImage.OutlinedScheduleIcon(),
@@ -45,6 +39,13 @@ export const getKebabMenuOptions = props => {
},
];
const share = {
label: t('share'),
icon: SvgImage.OutlinedShareIcon(),
onPress: loadScanScreen(VCShareFlowType.MINI_VIEW_SHARE),
testID: 'shareVcFromKebab',
};
const shareWithSelfieOption = {
label: t('shareWithSelfie'),
icon: SvgImage.OutlinedShareWithSelfieIcon(),
@@ -65,8 +66,12 @@ export const getKebabMenuOptions = props => {
testID: 'pendingActivationOrActivated',
};
if (props.vcHasImage) {
vcActionsList.splice(2, 0, shareWithSelfieOption, VCActivationOption);
if (props.vcMetadata.isVerified) {
vcActionsList.splice(1, 0, share);
if (props.vcHasImage) {
vcActionsList.splice(2, 0, shareWithSelfieOption);
}
vcActionsList.splice(3, 0, VCActivationOption);
}
return vcActionsList;

View File

@@ -6,7 +6,7 @@ import {Theme} from './styleUtils';
import {LoaderAnimation} from './LoaderAnimation';
import {Modal} from './Modal';
import {BannerNotification} from '../../components/BannerNotification';
import {BANNER_TYPE_SUCCESS, BANNER_TYPE_ERROR} from '../../shared/constants';
import { BannerStatusType } from '../../components/BannerNotification';
export const Loader: React.FC<LoaderProps> = props => {
const {t} = useTranslation('ScanScreen');
@@ -112,7 +112,7 @@ export const Loader: React.FC<LoaderProps> = props => {
<View style={Theme.Styles.hrLineFill}></View>
{props.showBanner && (
<BannerNotification
type={props.bannerType ? props.bannerType : BANNER_TYPE_SUCCESS}
type={props.bannerType ? props.bannerType : BannerStatusType.SUCCESS}
message={props.bannerMessage as string}
onClosePress={props.onBannerClose as () => void}
testId={props.bannerTestID as string}
@@ -142,6 +142,6 @@ export interface LoaderProps {
showBanner?: boolean;
bannerMessage?: string;
onBannerClose?: () => void;
bannerType?: typeof BANNER_TYPE_SUCCESS | typeof BANNER_TYPE_ERROR;
bannerType?: BannerStatusType;
bannerTestID?: string;
}

View File

@@ -1,25 +1,16 @@
import {Tooltip} from 'react-native-elements';
import {View} from 'react-native';
import {Centered, Column} from './Layout';
import {Text} from './Text';
import {Centered} from './Layout';
import React from 'react';
import {Theme} from './styleUtils';
import testIDProps from '../../shared/commonUtil';
import {StyleProp} from 'react-native';
import {ViewStyle} from 'react-native';
export const CustomTooltip: React.FC<CustomTooltipProps> = props => {
const tooltipContent = (
<Column>
<Text weight="semibold">{props.title}</Text>
<View style={Theme.Styles.tooltipHrLine}></View>
<Text weight="regular" style={Theme.Styles.tooltipContentDescription}>
{props.description}
</Text>
</Column>
);
return (
<Tooltip
{...testIDProps(props.testID)}
popover={tooltipContent}
popover={props.toolTipContent}
width={props.width}
height={props.height}
withPointer={true}
@@ -27,7 +18,7 @@ export const CustomTooltip: React.FC<CustomTooltipProps> = props => {
skipAndroidStatusBar={true}
pointerColor={Theme.Colors.toolTipPointerColor}
containerStyle={Theme.Styles.tooltipContainerStyle}>
<Centered width={32} fill>
<Centered style={props.triggerComponentStyles} fill>
{props.triggerComponent}
</Centered>
</Tooltip>
@@ -35,10 +26,10 @@ export const CustomTooltip: React.FC<CustomTooltipProps> = props => {
};
interface CustomTooltipProps {
title: string;
description: string;
width: number;
height: number;
triggerComponent: React.ReactElement;
testID?: string;
triggerComponentStyles: StyleProp<ViewStyle>;
testID: string;
toolTipContent?: React.ReactElement;
}

View File

@@ -49,6 +49,7 @@ import OutlinedDeleteIcon from '../../assets/Outlined_Delete_Icon.svg';
import OutlinedScheduleIcon from '../../assets/Outlined_Schedule_Icon.svg';
import OutlinedShareWithSelfieIcon from '../../assets/Outlined_Share_With_Selfie_Icon.svg';
import OutlinedShareIcon from '../../assets/Outlined_Share_Icon.svg';
import ColoredInfo from '../../assets/Colored_Info.svg';
import Info from '../../assets/Info.svg';
import Search from '../../assets/Search.svg';
import CloudUploadDoneIcon from '../../assets/Cloud_Upload_Done_Icon.svg';
@@ -415,12 +416,22 @@ export class SvgImage {
return <MagnifierZoom />;
}
static infoIcon() {
static coloredInfo() {
return (
<Info
<ColoredInfo
color1={Theme.Colors.linearGradientStart}
color2={Theme.Colors.linearGradientEnd}
style={Theme.Styles.infoIcon}
{...testIDProps('coloredInfoIcon')}
/>
);
}
static info() {
return (
<Info
color1={Theme.Colors.tooltipIcon}
width={16}
height={16}
{...testIDProps('infoIcon')}
/>
);

View File

@@ -60,6 +60,7 @@ const Colors = {
toolTipContent: '#4B4B4B',
toolTipPointer: '#E0E0E0',
Mercury: '#E6E6E6',
Yellow: '#E8A94F',
};
export type ElevationLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6;
@@ -138,6 +139,7 @@ export const DefaultTheme = {
toolTipPointerColor: Colors.toolTipPointer,
urlLink: Colors.Orange,
warningText: Colors.Red,
PendingIcon: Colors.Yellow,
},
Styles: StyleSheet.create({
title: {
@@ -195,10 +197,10 @@ export const DefaultTheme = {
justifyContent: 'center',
width: '15%',
},
verifiedIconContainer: {
verificationStatusIconContainer: {
marginRight: 3,
},
verifiedIconInner: {
verificationStatusIconInner: {
backgroundColor: 'white',
borderRadius: 10,
},
@@ -744,7 +746,7 @@ export const DefaultTheme = {
marginVertical: 1,
columnGap: 7,
},
topBanner : {
topBanner: {
marginTop: 10,
marginBottom: 10,
},
@@ -756,7 +758,7 @@ export const DefaultTheme = {
fontFamily: 'Inter_600SemiBold',
},
dismiss: {paddingLeft: 9},
info: {
inProgress: {
backgroundColor: Colors.OrangeBrown,
},
success: {
@@ -1261,7 +1263,9 @@ export const DefaultTheme = {
borderTopLeftRadius: 15,
borderTopRightRadius: 15,
width: Dimensions.get('screen').width,
marginTop: Dimensions.get('screen').height * 0.55,
maxHeight: 300,
position: 'absolute',
bottom: 0,
},
kebabHeaderStyle: {
justifyContent: 'space-between',
@@ -1499,24 +1503,24 @@ export const DefaultTheme = {
}),
HelpScreenStyle: StyleSheet.create({
viewStyle: {
width: 100,
padding: 7,
borderRadius: 8,
backgroundColor: Colors.LightOrange,
justifyContent: 'center',
alignItems: 'center',
paddingLeft: 16,
paddingRight: 16,
paddingBottom: 10,
paddingTop: 10,
},
rowStyle: {
justifyContent: 'space-between',
alignItems: 'center',
width: 45,
display: 'flex',
},
iconStyle: {
paddingTop: 7,
paddingLeft: 20,
paddingRight: 5,
},
labelStyle: {
width: 70,
fontWeight: 'bold',
},
}),

View File

@@ -63,6 +63,7 @@ const Colors = {
toolTipContent: '#4B4B4B',
toolTipPointer: '#E0E0E0',
Mercury: '#E6E6E6',
Yellow: '#E8A94F',
};
export type ElevationLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6;
@@ -141,6 +142,7 @@ export const PurpleTheme = {
toolTipPointerColor: Colors.toolTipPointer,
urlLink: Colors.Purple,
warningText: Colors.Red,
PendingIcon: Colors.Yellow,
},
Styles: StyleSheet.create({
title: {
@@ -199,10 +201,10 @@ export const PurpleTheme = {
justifyContent: 'center',
width: '15%',
},
verifiedIconContainer: {
verificationStatusIconContainer: {
marginRight: 3,
},
verifiedIconInner: {
verificationStatusIconInner: {
backgroundColor: 'white',
borderRadius: 10,
},
@@ -755,12 +757,12 @@ export const PurpleTheme = {
padding: 1,
fontFamily: 'Inter_600SemiBold',
},
topBanner : {
topBanner: {
marginTop: 10,
marginBottom: 10,
},
dismiss: {paddingLeft: 9},
info: {
inProgress: {
backgroundColor: Colors.OrangeBrown,
},
success: {
@@ -1262,7 +1264,9 @@ export const PurpleTheme = {
borderTopLeftRadius: 15,
borderTopRightRadius: 15,
width: Dimensions.get('screen').width,
marginTop: Dimensions.get('screen').height * 0.55,
maxHeight: 300,
position: 'absolute',
bottom: 0,
},
kebabHeaderStyle: {
justifyContent: 'space-between',
@@ -1500,24 +1504,24 @@ export const PurpleTheme = {
}),
HelpScreenStyle: StyleSheet.create({
viewStyle: {
width: 100,
padding: 7,
borderRadius: 8,
backgroundColor: Colors.LightPurple,
justifyContent: 'center',
alignItems: 'center',
paddingLeft: 16,
paddingRight: 16,
paddingBottom: 10,
paddingTop: 10,
},
rowStyle: {
justifyContent: 'space-between',
alignItems: 'center',
width: 45,
display: 'flex',
},
iconStyle: {
paddingTop: 7,
paddingLeft: 20,
paddingRight: 3,
paddingRight: 5,
},
labelStyle: {
width: 70,
fontWeight: 'bold',
},
}),

View File

@@ -46,6 +46,7 @@
"generatedOn": "تم إنشاؤه في",
"status": "الحالة",
"valid": "صالح",
"pending": "قيد الانتظار",
"photo": " صورة",
"fullName": "الاسم الكامل",
"gender": "الجنس",
@@ -408,9 +409,24 @@
"noReceivedVcsTitle": "لا يوجد بطاقة متاح حتى الآن",
"noReceivedVcsText": "اضغط على الطلب أدناه لتلقيبطاقة"
},
"VcVerificationBanner": {
"inProgress": "نحن نقوم بالتحقق من بطاقتك، قد يستغرق هذا بعض الوقت. بمجرد التحقق، ستتمكن من تفعيل بطاقتك.",
"success": "تم التحقق من {{vcDetails}} بنجاح وهو متاح الآن للتنشيط.",
"error": "عذرًا، لا يمكننا التحقق من {{vcDetails}} الآن. الرجاء معاودة المحاولة في وقت لاحق."
},
"ViewVcModal": {
"title": "تفاصيل الهوية",
"inProgress": "في تَقَدم"
"inProgress": "في تَقَدم",
"statusToolTipContent": {
"valid": {
"title": "حالة صالحة:",
"description": "تم التحقق من بيانات الاعتماد بنجاح."
},
"pending": {
"title": "وضع انتظار:",
"description": "التحقق معلق حاليًا بسبب مشكلات فنية."
}
}
},
"MainLayout": {
"home": "المنزل",
@@ -576,9 +592,9 @@
},
"ScanScreen": {
"shareWithSelfie": "شارك مع صورة شخصية",
"shareWithSelfieQrLogin":"ريال قطري رمز الدخول",
"shareWithSelfieQrLogin": "ريال قطري رمز الدخول",
"shareWithSelfieMessage": "لمشاركة بيانات الاعتماد التي يمكن التحقق منها، سنتحقق من هويتك بشكل آمن باستخدام التحقق من الوجه. من خلال المتابعة، فإنك توافق على استخدام INJI للكاميرا الخاصة بك لهذا الغرض. \n\n سيتم استخدام بيانات وجهك فقط للتحقق ولن تتم مشاركتها مع أي طرف ثالث.",
"shareWithSelfieMessageQrLogin":"من أجل الوصول إلى البوابة، ستحتاج إلى مشاركة بيانات الاعتماد التي يمكن التحقق منها والتحقق من هويتك بشكل آمن باستخدام التحقق من الوجه. من خلال المتابعة، فإنك توافق على استخدام Inji للكاميرا الخاصة بك لهذا الغرض. \n\n سيتم استخدام بيانات وجهك فقط للتحقق ولن تتم مشاركتها. بعد التحقق بنجاح، يمكنك اختيار التفاصيل التي تريد مشاركتها.",
"shareWithSelfieMessageQrLogin": "من أجل الوصول إلى البوابة، ستحتاج إلى مشاركة بيانات الاعتماد التي يمكن التحقق منها والتحقق من هويتك بشكل آمن باستخدام التحقق من الوجه. من خلال المتابعة، فإنك توافق على استخدام Inji للكاميرا الخاصة بك لهذا الغرض. \n\n سيتم استخدام بيانات وجهك فقط للتحقق ولن تتم مشاركتها. بعد التحقق بنجاح، يمكنك اختيار التفاصيل التي تريد مشاركتها.",
"ConfirmButton": "أفهم",
"doNotAskMessage": "لا تسألني مرة أخرى",
"noShareableVcs": "لا تتوفر بطاقات قابلة للمشاركة",

View File

@@ -46,6 +46,7 @@
"generatedOn": "Generated On",
"status": "Status",
"valid": "Valid",
"pending": "Pending",
"photo": "Photo",
"fullName": "Full Name",
"gender": "Gender",
@@ -409,9 +410,24 @@
"noReceivedVcsTitle": "No card available yet",
"noReceivedVcsText": "Tap on Request below to receive card"
},
"VcVerificationBanner": {
"inProgress": "We are validating your card, this may take sometime. Once verified, youll be able to activate your card.",
"success": "{{vcDetails}} is verified successfully and now available for activation.",
"error": "Sorry, we are unable to verify the {{vcDetails}} right now. Please try again later."
},
"ViewVcModal": {
"title": "ID Details",
"inProgress": "In Progress"
"inProgress": "In Progress",
"statusToolTipContent": {
"valid": {
"title": "Valid Status:",
"description": "The credential has been successfully verified."
},
"pending": {
"title": "Pending Status:",
"description": "Verification is currently pending due to technical issues."
}
}
},
"MainLayout": {
"home": "Home",
@@ -580,9 +596,9 @@
},
"ScanScreen": {
"shareWithSelfie": "Share with Selfie",
"shareWithSelfieQrLogin":"QR Code Login",
"shareWithSelfieQrLogin": "QR Code Login",
"shareWithSelfieMessage": "To share your Verifiable Credentials, well securely verify your identity using face verification. By continuing, you consent to INJI using your camera for this purpose. \n\n Your facial data will only be used for verification and will not be shared with any third parties.",
"shareWithSelfieMessageQrLogin":"In order to access the portal, youll need to share your Verifiable Credentials and verify your identity securely using face verification. By continuing, you consent to Inji using your camera for this purpose. \n\n Your facial data will only be used for verification and will not be shared. After successful verification, you can choose which details to share.",
"shareWithSelfieMessageQrLogin": "In order to access the portal, youll need to share your Verifiable Credentials and verify your identity securely using face verification. By continuing, you consent to Inji using your camera for this purpose. \n\n Your facial data will only be used for verification and will not be shared. After successful verification, you can choose which details to share.",
"ConfirmButton": "I Understand",
"doNotAskMessage": "Don't ask me again",
"noShareableVcs": "No shareable cards are available.",

View File

@@ -46,6 +46,7 @@
"generatedOn": "Nilikha noong",
"status": "Katayuan",
"valid": "Napatunayan",
"pending": "Nakabinbin",
"photo": "Larawan",
"fullName": "Buong pangalan",
"gender": "Kasarian",
@@ -408,9 +409,24 @@
"noReceivedVcsTitle": "Wala pang card",
"noReceivedVcsText": "Pindutin ang Humiling sa ibaba para makatanggap ng card"
},
"VcVerificationBanner": {
"inProgress": "Pina-validate namin ang iyong card, maaaring magtagal ito. Kapag na-verify na, magagawa mong i-activate ang iyong card.",
"success": "Matagumpay na na-verify ang {{vcDetails}} at magagamit na ngayon para sa pag-activate.",
"error": "Paumanhin, hindi namin ma-verify ang {{vcDetails}} ngayon. Subukang muli mamaya."
},
"ViewVcModal": {
"title": "Mga Detalye ng ID",
"inProgress": "Isinasagawa"
"inProgress": "Isinasagawa",
"statusToolTipContent": {
"valid": {
"title": "Wastong Katayuan:",
"description": "Matagumpay na na-verify ang kredensyal."
},
"pending": {
"title": "Nakabinbing Katayuan:",
"description": "Kasalukuyang nakabinbin ang pag-verify dahil sa mga teknikal na isyu."
}
}
},
"MainLayout": {
"home": "Bahay",

View File

@@ -46,6 +46,7 @@
"generatedOn": "पर उत्पन्न हुआ",
"status": "दर्जा",
"valid": "वैध",
"pending": "लंबित",
"photo": "फ़ोटो",
"fullName": "पूरा नाम",
"gender": "लिंग",
@@ -410,9 +411,24 @@
"noReceivedVcsTitle": "नहीं कार्ड अभी तक उपलब्ध नहीं है",
"noReceivedVcsText": "प्राप्त करने के लिए नीचे दिए गए अनुरोध पर टैप करें कार्ड"
},
"VcVerificationBanner": {
"inProgress": "हम आपके कार्ड का सत्यापन कर रहे हैं, इसमें कुछ समय लग सकता है। एक बार सत्यापित हो जाने पर, आप अपना कार्ड सक्रिय कर सकेंगे।",
"success": "{{vcDetails}} सफलतापूर्वक सत्यापित हो गया है और अब सक्रियण के लिए उपलब्ध है।",
"error": "क्षमा करें, हम अभी {{vcDetails}} को सत्यापित करने में असमर्थ हैं। कृपया बाद में पुन: प्रयास करें।"
},
"ViewVcModal": {
"title": "आईडी विवरण",
"inProgress": "चालू"
"inProgress": "चालू",
"statusToolTipContent": {
"valid": {
"title": "वैध स्थिति:",
"description": "क्रेडेंशियल सफलतापूर्वक सत्यापित किया गया है."
},
"pending": {
"title": "लंबित स्थिति:",
"description": "तकनीकी समस्याओं के कारण सत्यापन फिलहाल लंबित है।"
}
}
},
"MainLayout": {
"home": "होम",

View File

@@ -46,6 +46,7 @@
"generatedOn": "ಜನರೇಟೆಡ್ ಆನ್",
"status": "ಸ್ಥಿತಿ",
"valid": "ಮಾನ್ಯ",
"pending": "ಬಾಕಿಯಿದೆ",
"photo": "ಫೋಟೋ",
"fullName": "ಪೂರ್ಣ ಹೆಸರು",
"gender": "ಲಿಂಗ",
@@ -408,9 +409,24 @@
"noReceivedVcsTitle": "ಇನ್ನೂ ಯಾವುದೇ ಕಾರ್ಡ್ ಲಭ್ಯವಿಲ್ಲ",
"noReceivedVcsText": "ಕಾರ್ಡ್ ಸ್ವೀಕರಿಸಲು ಕೆಳಗಿನ ವಿನಂತಿಯ ಮೇಲೆ ಟ್ಯಾಪ್ ಮಾಡಿ"
},
"VcVerificationBanner": {
"inProgress": "ನಾವು ನಿಮ್ಮ ಕಾರ್ಡ್ ಅನ್ನು ಮೌಲ್ಯೀಕರಿಸುತ್ತಿದ್ದೇವೆ, ಇದಕ್ಕೆ ಸ್ವಲ್ಪ ಸಮಯ ತೆಗೆದುಕೊಳ್ಳಬಹುದು. ಒಮ್ಮೆ ಪರಿಶೀಲಿಸಿದ ನಂತರ, ನಿಮ್ಮ ಕಾರ್ಡ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲು ನಿಮಗೆ ಸಾಧ್ಯವಾಗುತ್ತದೆ.",
"success": "{{vcDetails}} ಅನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಪರಿಶೀಲಿಸಲಾಗಿದೆ ಮತ್ತು ಇದೀಗ ಸಕ್ರಿಯಗೊಳಿಸುವಿಕೆಗೆ ಲಭ್ಯವಿದೆ.",
"error": "ಕ್ಷಮಿಸಿ, ಇದೀಗ {{vcDetails}} ಅನ್ನು ಪರಿಶೀಲಿಸಲು ನಮಗೆ ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ. ದಯವಿಟ್ಟು ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."
},
"ViewVcModal": {
"title": "ಐಡಿ ವಿವರಗಳು",
"inProgress": "ಪ್ರಗತಿಯಲ್ಲಿದೆ"
"inProgress": "ಪ್ರಗತಿಯಲ್ಲಿದೆ",
"statusToolTipContent": {
"valid": {
"title": "ಮಾನ್ಯ ಸ್ಥಿತಿ:",
"description": "ರುಜುವಾತುಗಳನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಪರಿಶೀಲಿಸಲಾಗಿದೆ."
},
"pending": {
"title": "ಬಾಕಿ ಉಳಿದಿರುವ ಸ್ಥಿತಿ:",
"description": "ತಾಂತ್ರಿಕ ಸಮಸ್ಯೆಗಳಿಂದ ಪರಿಶೀಲನೆಯು ಪ್ರಸ್ತುತ ಬಾಕಿ ಉಳಿದಿದೆ."
}
}
},
"MainLayout": {
"home": "ಮನೆ",

View File

@@ -46,6 +46,7 @@
"generatedOn": "உருவாக்கப்பட்டது",
"status": "நிலை",
"valid": "செல்லுபடியாகும்",
"pending": "நிலுவையில் உள்ளது",
"photo": "புகைப்படம்",
"fullName": "முழு பெயர்",
"gender": "பாலினம்",
@@ -408,9 +409,24 @@
"noReceivedVcsTitle": "இன்னும் அட்டை கிடைக்கவில்லை",
"noReceivedVcsText": "அட்டை பெறுவதற்கு கீழே உள்ள கோரிக்கையைத் தட்டவும்"
},
"VcVerificationBanner": {
"inProgress": "உங்கள் கார்டை நாங்கள் சரிபார்க்கிறோம், இதற்கு சிறிது நேரம் ஆகலாம். சரிபார்க்கப்பட்டதும், உங்கள் கார்டைச் செயல்படுத்த முடியும்.",
"success": "{{vcDetails}} வெற்றிகரமாகச் சரிபார்க்கப்பட்டது, இப்போது செயல்படுத்துவதற்குக் கிடைக்கிறது.",
"error": "மன்னிக்கவும், இப்போது எங்களால் {{vcDetails}} ஐச் சரிபார்க்க முடியவில்லை. பிறகு முயற்சிக்கவும்."
},
"ViewVcModal": {
"title": "அடையாள விவரங்கள்",
"inProgress": "செயல்பாட்டில் உள்ளது"
"inProgress": "செயல்பாட்டில் உள்ளது",
"statusToolTipContent": {
"valid": {
"title": "செல்லுபடியாகும் நிலை:",
"description": "நற்சான்றிதழ் வெற்றிகரமாகச் சரிபார்க்கப்பட்டது."
},
"pending": {
"title": "நிலுவையில் உள்ள நிலை:",
"description": "தொழில்நுட்ப சிக்கல்கள் காரணமாக சரிபார்ப்பு தற்போது நிலுவையில் உள்ளது."
}
}
},
"MainLayout": {
"home": "வீடு",

View File

@@ -1,108 +1,213 @@
// This file was automatically generated. Edits will be overwritten
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"done.invoke.checkInternet": { type: "done.invoke.checkInternet"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.displayIssuers:invocation[0]": { type: "done.invoke.issuersMachine.displayIssuers:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]": { type: "done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.downloadCredentials:invocation[0]": { type: "done.invoke.issuersMachine.downloadCredentials:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]": { type: "done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.generateKeyPair:invocation[0]": { type: "done.invoke.issuersMachine.generateKeyPair:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.performAuthorization:invocation[0]": { type: "done.invoke.issuersMachine.performAuthorization:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.storing:invocation[0]": { type: "done.invoke.issuersMachine.storing:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.issuersMachine.verifyingCredential:invocation[0]": { type: "done.invoke.issuersMachine.verifyingCredential:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"error.platform.checkInternet": { type: "error.platform.checkInternet"; data: unknown };
"error.platform.issuersMachine.displayIssuers:invocation[0]": { type: "error.platform.issuersMachine.displayIssuers:invocation[0]"; data: unknown };
"error.platform.issuersMachine.downloadCredentialTypes:invocation[0]": { type: "error.platform.issuersMachine.downloadCredentialTypes:invocation[0]"; data: unknown };
"error.platform.issuersMachine.downloadCredentials:invocation[0]": { type: "error.platform.issuersMachine.downloadCredentials:invocation[0]"; data: unknown };
"error.platform.issuersMachine.downloadIssuerConfig:invocation[0]": { type: "error.platform.issuersMachine.downloadIssuerConfig:invocation[0]"; data: unknown };
"error.platform.issuersMachine.performAuthorization:invocation[0]": { type: "error.platform.issuersMachine.performAuthorization:invocation[0]"; data: unknown };
"error.platform.issuersMachine.verifyingCredential:invocation[0]": { type: "error.platform.issuersMachine.verifyingCredential:invocation[0]"; data: unknown };
"xstate.init": { type: "xstate.init" };
};
invokeSrcNameMap: {
"checkInternet": "done.invoke.checkInternet";
"downloadCredential": "done.invoke.issuersMachine.downloadCredentials:invocation[0]";
"downloadCredentialTypes": "done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]";
"downloadIssuerConfig": "done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]";
"downloadIssuersList": "done.invoke.issuersMachine.displayIssuers:invocation[0]";
"generateKeyPair": "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"invokeAuthorization": "done.invoke.issuersMachine.performAuthorization:invocation[0]";
"isUserSignedAlready": "done.invoke.issuersMachine.storing:invocation[0]";
"verifyCredential": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
};
missingImplementations: {
actions: "getKeyPairFromStore" | "loadKeyPair" | "logDownloaded" | "resetError" | "resetLoadingReason" | "resetVerificationErrorMessage" | "sendBackupEvent" | "sendErrorEndEvent" | "sendImpressionEvent" | "sendSuccessEndEvent" | "setCredentialTypes" | "setCredentialWrapper" | "setError" | "setIssuers" | "setLoadingReasonAsDisplayIssuers" | "setLoadingReasonAsDownloadingCredentials" | "setLoadingReasonAsSettingUp" | "setMetadataInCredentialData" | "setNoInternet" | "setOIDCConfigError" | "setPrivateKey" | "setPublicKey" | "setSelectedCredentialType" | "setSelectedIssuerId" | "setSelectedIssuers" | "setTokenResponse" | "setVCMetadata" | "setVerifiableCredential" | "storeKeyPair" | "storeVcMetaContext" | "storeVcsContext" | "storeVerifiableCredentialData" | "storeVerifiableCredentialMeta" | "updateVerificationErrorMessage";
delays: never;
guards: "canSelectIssuerAgain" | "hasKeyPair" | "hasUserCancelledBiometric" | "isCustomSecureKeystore" | "isInternetConnected" | "isMultipleCredentialsSupported" | "isOIDCConfigError" | "isOIDCflowCancelled" | "isSignedIn" | "shouldFetchIssuersAgain";
services: "checkInternet" | "downloadCredential" | "downloadCredentialTypes" | "downloadIssuerConfig" | "downloadIssuersList" | "generateKeyPair" | "invokeAuthorization" | "isUserSignedAlready" | "verifyCredential";
};
eventsCausingActions: {
"getKeyPairFromStore": "TRY_AGAIN" | "done.invoke.issuersMachine.performAuthorization:invocation[0]";
"loadKeyPair": "STORE_RESPONSE";
"logDownloaded": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"resetError": "RESET_ERROR" | "TRY_AGAIN" | "error.platform.issuersMachine.performAuthorization:invocation[0]";
"resetLoadingReason": "RESET_ERROR" | "done.invoke.checkInternet" | "done.invoke.issuersMachine.displayIssuers:invocation[0]" | "error.platform.issuersMachine.downloadCredentialTypes:invocation[0]" | "error.platform.issuersMachine.downloadCredentials:invocation[0]" | "error.platform.issuersMachine.downloadIssuerConfig:invocation[0]" | "error.platform.issuersMachine.performAuthorization:invocation[0]" | "error.platform.issuersMachine.verifyingCredential:invocation[0]";
"resetVerificationErrorMessage": "RESET_VERIFY_ERROR";
"sendBackupEvent": "done.invoke.issuersMachine.storing:invocation[0]";
"sendErrorEndEvent": "error.platform.issuersMachine.verifyingCredential:invocation[0]";
"sendImpressionEvent": "done.invoke.issuersMachine.displayIssuers:invocation[0]";
"sendSuccessEndEvent": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"setCredentialTypes": "done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]";
"setCredentialWrapper": "done.invoke.issuersMachine.downloadCredentials:invocation[0]";
"setError": "error.platform.issuersMachine.displayIssuers:invocation[0]" | "error.platform.issuersMachine.downloadCredentialTypes:invocation[0]" | "error.platform.issuersMachine.downloadCredentials:invocation[0]" | "error.platform.issuersMachine.downloadIssuerConfig:invocation[0]" | "error.platform.issuersMachine.performAuthorization:invocation[0]";
"setIssuers": "done.invoke.issuersMachine.displayIssuers:invocation[0]";
"setLoadingReasonAsDisplayIssuers": "TRY_AGAIN";
"setLoadingReasonAsDownloadingCredentials": "STORE_ERROR" | "STORE_RESPONSE" | "TRY_AGAIN" | "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"setLoadingReasonAsSettingUp": "SELECTED_ISSUER" | "TRY_AGAIN" | "done.invoke.issuersMachine.performAuthorization:invocation[0]";
"setMetadataInCredentialData": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"setNoInternet": "done.invoke.checkInternet";
"setOIDCConfigError": "error.platform.issuersMachine.performAuthorization:invocation[0]";
"setPrivateKey": "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"setPublicKey": "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"setSelectedCredentialType": "SELECTED_CREDENTIAL_TYPE";
"setSelectedIssuerId": "SELECTED_ISSUER";
"setSelectedIssuers": "done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]";
"setTokenResponse": "done.invoke.issuersMachine.performAuthorization:invocation[0]";
"setVCMetadata": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"setVerifiableCredential": "done.invoke.issuersMachine.downloadCredentials:invocation[0]";
"storeKeyPair": "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"storeVcMetaContext": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"storeVcsContext": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"storeVerifiableCredentialData": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"storeVerifiableCredentialMeta": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"updateVerificationErrorMessage": "error.platform.issuersMachine.verifyingCredential:invocation[0]";
};
eventsCausingDelays: {
};
eventsCausingGuards: {
"canSelectIssuerAgain": "TRY_AGAIN";
"hasKeyPair": "CHECK_KEY_PAIR";
"hasUserCancelledBiometric": "error.platform.issuersMachine.downloadCredentials:invocation[0]";
"isCustomSecureKeystore": "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"isInternetConnected": "done.invoke.checkInternet";
"isMultipleCredentialsSupported": "done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]";
"isOIDCConfigError": "error.platform.issuersMachine.performAuthorization:invocation[0]";
"isOIDCflowCancelled": "error.platform.issuersMachine.performAuthorization:invocation[0]";
"isSignedIn": "done.invoke.issuersMachine.storing:invocation[0]";
"shouldFetchIssuersAgain": "TRY_AGAIN";
};
eventsCausingServices: {
"checkInternet": "SELECTED_CREDENTIAL_TYPE" | "done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]";
"downloadCredential": "CHECK_KEY_PAIR" | "done.invoke.issuersMachine.generateKeyPair:invocation[0]";
"downloadCredentialTypes": "done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]";
"downloadIssuerConfig": "SELECTED_ISSUER" | "TRY_AGAIN";
"downloadIssuersList": "CANCEL" | "TRY_AGAIN" | "xstate.init";
"generateKeyPair": "CHECK_KEY_PAIR";
"invokeAuthorization": "done.invoke.checkInternet";
"isUserSignedAlready": "done.invoke.issuersMachine.verifyingCredential:invocation[0]";
"verifyCredential": "done.invoke.issuersMachine.downloadCredentials:invocation[0]";
};
matchesStates: "checkInternet" | "checkKeyPair" | "displayIssuers" | "done" | "downloadCredentialTypes" | "downloadCredentials" | "downloadCredentials.idle" | "downloadCredentials.userCancelledBiometric" | "downloadIssuerConfig" | "error" | "generateKeyPair" | "handleVCVerificationFailure" | "idle" | "performAuthorization" | "performAuthorization.idle" | "performAuthorization.userCancelledBiometric" | "selectingCredentialType" | "selectingIssuer" | "storing" | "verifyingCredential" | { "downloadCredentials"?: "idle" | "userCancelledBiometric";
"performAuthorization"?: "idle" | "userCancelledBiometric"; };
tags: never;
}
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'done.invoke.checkInternet': {
type: 'done.invoke.checkInternet';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.displayIssuers:invocation[0]': {
type: 'done.invoke.issuersMachine.displayIssuers:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]': {
type: 'done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.downloadCredentials:invocation[0]': {
type: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]': {
type: 'done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.generateKeyPair:invocation[0]': {
type: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.performAuthorization:invocation[0]': {
type: 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.storing:invocation[0]': {
type: 'done.invoke.issuersMachine.storing:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.issuersMachine.verifyingCredential:invocation[0]': {
type: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'error.platform.checkInternet': {
type: 'error.platform.checkInternet';
data: unknown;
};
'error.platform.issuersMachine.displayIssuers:invocation[0]': {
type: 'error.platform.issuersMachine.displayIssuers:invocation[0]';
data: unknown;
};
'error.platform.issuersMachine.downloadCredentialTypes:invocation[0]': {
type: 'error.platform.issuersMachine.downloadCredentialTypes:invocation[0]';
data: unknown;
};
'error.platform.issuersMachine.downloadCredentials:invocation[0]': {
type: 'error.platform.issuersMachine.downloadCredentials:invocation[0]';
data: unknown;
};
'error.platform.issuersMachine.downloadIssuerConfig:invocation[0]': {
type: 'error.platform.issuersMachine.downloadIssuerConfig:invocation[0]';
data: unknown;
};
'error.platform.issuersMachine.performAuthorization:invocation[0]': {
type: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
data: unknown;
};
'error.platform.issuersMachine.verifyingCredential:invocation[0]': {
type: 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
data: unknown;
};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
checkInternet: 'done.invoke.checkInternet';
downloadCredential: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
downloadCredentialTypes: 'done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]';
downloadIssuerConfig: 'done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]';
downloadIssuersList: 'done.invoke.issuersMachine.displayIssuers:invocation[0]';
generateKeyPair: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
invokeAuthorization: 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
isUserSignedAlready: 'done.invoke.issuersMachine.storing:invocation[0]';
verifyCredential: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
getKeyPairFromStore:
| 'TRY_AGAIN'
| 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
loadKeyPair: 'STORE_RESPONSE';
logDownloaded: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
resetError:
| 'RESET_ERROR'
| 'TRY_AGAIN'
| 'error.platform.issuersMachine.performAuthorization:invocation[0]';
resetLoadingReason:
| 'RESET_ERROR'
| 'done.invoke.checkInternet'
| 'done.invoke.issuersMachine.displayIssuers:invocation[0]'
| 'error.platform.issuersMachine.downloadCredentialTypes:invocation[0]'
| 'error.platform.issuersMachine.downloadCredentials:invocation[0]'
| 'error.platform.issuersMachine.downloadIssuerConfig:invocation[0]'
| 'error.platform.issuersMachine.performAuthorization:invocation[0]'
| 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
resetVerificationErrorMessage: 'RESET_VERIFY_ERROR';
sendBackupEvent: 'done.invoke.issuersMachine.storing:invocation[0]';
sendErrorEndEvent: 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
sendImpressionEvent: 'done.invoke.issuersMachine.displayIssuers:invocation[0]';
sendSuccessEndEvent: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
setCredentialTypes: 'done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]';
setCredentialWrapper: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
setError:
| 'error.platform.issuersMachine.displayIssuers:invocation[0]'
| 'error.platform.issuersMachine.downloadCredentialTypes:invocation[0]'
| 'error.platform.issuersMachine.downloadCredentials:invocation[0]'
| 'error.platform.issuersMachine.downloadIssuerConfig:invocation[0]'
| 'error.platform.issuersMachine.performAuthorization:invocation[0]';
setIssuers: 'done.invoke.issuersMachine.displayIssuers:invocation[0]';
setLoadingReasonAsDisplayIssuers: 'TRY_AGAIN';
setLoadingReasonAsDownloadingCredentials:
| 'STORE_ERROR'
| 'STORE_RESPONSE'
| 'TRY_AGAIN'
| 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
setLoadingReasonAsSettingUp:
| 'SELECTED_ISSUER'
| 'TRY_AGAIN'
| 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
setMetadataInCredentialData: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
setNoInternet: 'done.invoke.checkInternet';
setOIDCConfigError: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
setPrivateKey: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
setPublicKey: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
setSelectedCredentialType: 'SELECTED_CREDENTIAL_TYPE';
setSelectedIssuerId: 'SELECTED_ISSUER';
setSelectedIssuers: 'done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]';
setTokenResponse: 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
setVCMetadata: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
setVerifiableCredential: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
storeKeyPair: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
storeVcMetaContext: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
storeVcsContext: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
storeVerifiableCredentialData: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
storeVerifiableCredentialMeta: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
updateVerificationErrorMessage: 'error.platform.issuersMachine.verifyingCredential:invocation[0]';
};
eventsCausingDelays: {};
eventsCausingGuards: {
canSelectIssuerAgain: 'TRY_AGAIN';
hasKeyPair: 'CHECK_KEY_PAIR';
hasUserCancelledBiometric: 'error.platform.issuersMachine.downloadCredentials:invocation[0]';
isCustomSecureKeystore: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
isInternetConnected: 'done.invoke.checkInternet';
isMultipleCredentialsSupported: 'done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]';
isOIDCConfigError: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
isOIDCflowCancelled: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
isSignedIn: 'done.invoke.issuersMachine.storing:invocation[0]';
shouldFetchIssuersAgain: 'TRY_AGAIN';
};
eventsCausingServices: {
checkInternet:
| 'SELECTED_CREDENTIAL_TYPE'
| 'done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]';
downloadCredential:
| 'CHECK_KEY_PAIR'
| 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
downloadCredentialTypes: 'done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]';
downloadIssuerConfig: 'SELECTED_ISSUER' | 'TRY_AGAIN';
downloadIssuersList: 'CANCEL' | 'TRY_AGAIN' | 'xstate.init';
generateKeyPair: 'CHECK_KEY_PAIR';
invokeAuthorization: 'done.invoke.checkInternet';
isUserSignedAlready: 'done.invoke.issuersMachine.verifyingCredential:invocation[0]';
verifyCredential: 'done.invoke.issuersMachine.downloadCredentials:invocation[0]';
};
matchesStates:
| 'checkInternet'
| 'checkKeyPair'
| 'displayIssuers'
| 'done'
| 'downloadCredentialTypes'
| 'downloadCredentials'
| 'downloadCredentials.idle'
| 'downloadCredentials.userCancelledBiometric'
| 'downloadIssuerConfig'
| 'error'
| 'generateKeyPair'
| 'handleVCVerificationFailure'
| 'idle'
| 'performAuthorization'
| 'performAuthorization.idle'
| 'performAuthorization.userCancelledBiometric'
| 'selectingCredentialType'
| 'selectingIssuer'
| 'storing'
| 'verifyingCredential'
| {
downloadCredentials?: 'idle' | 'userCancelledBiometric';
performAuthorization?: 'idle' | 'userCancelledBiometric';
};
tags: never;
}

View File

@@ -1,170 +1,177 @@
import { assign, send, sendParent } from "xstate";
import i18n from "../../i18n";
import { VCShareFlowType } from "../../shared/Utils";
import { parseMetadatas } from "../../shared/VCMetadata";
import { SHOW_FACE_AUTH_CONSENT_QR_LOGIN_FLOW, MY_VCS_STORE_KEY } from "../../shared/constants";
import { getBindingCertificateConstant } from "../../shared/keystore/SecureKeystore";
import { VC, linkTransactionResponse } from "../VerifiableCredential/VCMetaMachine/vc";
import { StoreEvents } from "../store";
import {assign, send, sendParent} from 'xstate';
import i18n from '../../i18n';
import {VCShareFlowType} from '../../shared/Utils';
import {parseMetadatas} from '../../shared/VCMetadata';
import {
SHOW_FACE_AUTH_CONSENT_QR_LOGIN_FLOW,
MY_VCS_STORE_KEY,
} from '../../shared/constants';
import {getBindingCertificateConstant} from '../../shared/keystore/SecureKeystore';
import {
VC,
linkTransactionResponse,
} from '../VerifiableCredential/VCMetaMachine/vc';
import {StoreEvents} from '../store';
export const QrLoginActions = (model: any) => {
return {
setShowFaceAuthConsent: model.assign({
showFaceAuthConsent: (_, event) => {
return !event.isDoNotAskAgainChecked;
},
}),
export const QrLoginActions=(model:any)=>{
return{
setShowFaceAuthConsent: model.assign({
showFaceAuthConsent: (_, event) => {
return !event.isDoNotAskAgainChecked;
},
}),
storeShowFaceAuthConsent: send(
(context, event) =>
StoreEvents.SET(SHOW_FACE_AUTH_CONSENT_QR_LOGIN_FLOW, !event.isDoNotAskAgainChecked),
{
to: context => context.serviceRefs.store,
},
storeShowFaceAuthConsent: send(
(context, event) =>
StoreEvents.SET(
SHOW_FACE_AUTH_CONSENT_QR_LOGIN_FLOW,
!event.isDoNotAskAgainChecked,
),
{
to: context => context.serviceRefs.store,
},
),
forwardToParent: sendParent('DISMISS'),
forwardToParent: sendParent('DISMISS'),
setScanData: model.assign((context, event) => {
const linkCode = event.linkCode;
const flowType = event.flowType;
const selectedVc = event.selectedVc;
return {
...context,
linkCode: linkCode,
flowType: flowType,
selectedVc: selectedVc,
};
}),
getFaceAuthConsent: send(StoreEvents.GET(SHOW_FACE_AUTH_CONSENT_QR_LOGIN_FLOW), {
to: (context:any) => context.serviceRefs.store,
}),
setScanData: model.assign((context, event) => {
const linkCode = event.linkCode;
const flowType = event.flowType;
const selectedVc = event.selectedVc;
return {
...context,
linkCode: linkCode,
flowType: flowType,
selectedVc: selectedVc,
};
}),
getFaceAuthConsent: send(
StoreEvents.GET(SHOW_FACE_AUTH_CONSENT_QR_LOGIN_FLOW),
{
to: (context: any) => context.serviceRefs.store,
},
),
updateShowFaceAuthConsent: model.assign({
showFaceAuthConsent: (_, event) => {
return event.response || event.response === null;
},
}),
updateShowFaceAuthConsent: model.assign({
showFaceAuthConsent: (_, event) => {
return event.response || event.response === null;
},
}),
// TODO: loaded VCMetadatas are not used anywhere. remove?
loadMyVcs: send(StoreEvents.GET(MY_VCS_STORE_KEY), {
to: context => context.serviceRefs.store,
}),
// TODO: loaded VCMetadatas are not used anywhere. remove?
loadMyVcs: send(StoreEvents.GET(MY_VCS_STORE_KEY), {
to: context => context.serviceRefs.store,
}),
setMyVcs: model.assign({
myVcs: (_context, event) =>
parseMetadatas((event.response || []) as object[]),
}),
setMyVcs: model.assign({
myVcs: (_context, event) =>
parseMetadatas((event.response || []) as object[]),
}),
loadThumbprint: send(
context =>
StoreEvents.GET(
getBindingCertificateConstant(
context.selectedVc.walletBindingResponse?.walletBindingId,
),
),
{to: context => context.serviceRefs.store},
loadThumbprint: send(
context =>
StoreEvents.GET(
getBindingCertificateConstant(
context.selectedVc.walletBindingResponse?.walletBindingId,
),
),
setThumbprint: assign({
thumbprint: (_context, event) => {
return (event.response || '') as string;
},
}),
resetLinkTransactionId: model.assign({
linkTransactionId: () => '',
}),
{to: context => context.serviceRefs.store},
),
setThumbprint: assign({
thumbprint: (_context, event) => {
return (event.response || '') as string;
},
}),
resetLinkTransactionId: model.assign({
linkTransactionId: () => '',
}),
resetSelectedVoluntaryClaims: model.assign({
selectedVoluntaryClaims: () => [],
}),
resetSelectedVoluntaryClaims: model.assign({
selectedVoluntaryClaims: () => [],
}),
setSelectedVc: assign({
selectedVc: (context, event) => {
return {...event.vc};
},
}),
setSelectedVc: assign({
selectedVc: (context, event) => {
return {...event.vc};
},
}),
resetSelectedVc: assign({
selectedVc: {} as VC,
}),
resetSelectedVc: assign({
selectedVc: {} as VC,
}),
resetFlowType: assign({
flowType: VCShareFlowType.SIMPLE_SHARE,
}),
resetFlowType: assign({
flowType: VCShareFlowType.SIMPLE_SHARE,
}),
setlinkTransactionResponse: assign({
linkTransactionResponse: (context, event) =>
event.data as linkTransactionResponse,
}),
setlinkTransactionResponse: assign({
linkTransactionResponse: (context, event) =>
event.data as linkTransactionResponse,
}),
expandLinkTransResp: assign({
authFactors: context => context.linkTransactionResponse.authFactors,
expandLinkTransResp: assign({
authFactors: context => context.linkTransactionResponse.authFactors,
authorizeScopes: context =>
context.linkTransactionResponse.authorizeScopes,
authorizeScopes: context =>
context.linkTransactionResponse.authorizeScopes,
clientName: context => context.linkTransactionResponse.clientName,
clientName: context => context.linkTransactionResponse.clientName,
configs: context => context.linkTransactionResponse.configs,
configs: context => context.linkTransactionResponse.configs,
essentialClaims: context =>
context.linkTransactionResponse.essentialClaims,
essentialClaims: context =>
context.linkTransactionResponse.essentialClaims,
linkTransactionId: context =>
context.linkTransactionResponse.linkTransactionId,
linkTransactionId: context =>
context.linkTransactionResponse.linkTransactionId,
logoUrl: context => context.linkTransactionResponse.logoUrl,
logoUrl: context => context.linkTransactionResponse.logoUrl,
voluntaryClaims: context =>
context.linkTransactionResponse.voluntaryClaims,
}),
voluntaryClaims: context =>
context.linkTransactionResponse.voluntaryClaims,
}),
setClaims: context => {
context.voluntaryClaims.map(claim => {
context.isSharing[claim] = false;
});
},
setClaims: context => {
context.voluntaryClaims.map(claim => {
context.isSharing[claim] = false;
});
},
SetErrorMessage: assign({
errorMessage: (context, event) => {
const message = event.data.name;
const ID_ERRORS_MAP = {
invalid_link_code: 'invalidQR',
};
const errorMessage = ID_ERRORS_MAP[message]
? i18n.t(`errors.${ID_ERRORS_MAP[message]}`, {
ns: 'QrLogin',
})
: i18n.t(`errors.genericError`, {
ns: 'common',
});
SetErrorMessage: assign({
errorMessage: (context, event) => {
const message = event.data.name;
const ID_ERRORS_MAP = {
invalid_link_code: 'invalidQR',
};
const errorMessage = ID_ERRORS_MAP[message]
? i18n.t(`errors.${ID_ERRORS_MAP[message]}`, {
ns: 'QrLogin',
})
: i18n.t(`errors.genericError`, {
ns: 'common',
});
return errorMessage;
},
}),
return errorMessage;
},
}),
setConsentClaims: assign({
isSharing: (context, event) => {
context.isSharing[event.claim] = !event.enable;
if (!event.enable) {
context.selectedVoluntaryClaims.push(event.claim);
} else {
context.selectedVoluntaryClaims =
context.selectedVoluntaryClaims.filter(
eachClaim => eachClaim !== event.claim,
);
}
return {...context.isSharing};
},
}),
setLinkedTransactionId: assign({
linkedTransactionId: (context, event) =>
event.data.linkedTransactionId as string,
}),
}
}
setConsentClaims: assign({
isSharing: (context, event) => {
context.isSharing[event.claim] = !event.enable;
if (!event.enable) {
context.selectedVoluntaryClaims.push(event.claim);
} else {
context.selectedVoluntaryClaims =
context.selectedVoluntaryClaims.filter(
eachClaim => eachClaim !== event.claim,
);
}
return {...context.isSharing};
},
}),
setLinkedTransactionId: assign({
linkedTransactionId: (context, event) =>
event.data.linkedTransactionId as string,
}),
};
};

View File

@@ -1,13 +1,13 @@
import { VCShareFlowType } from "../../shared/Utils";
import {VCShareFlowType} from '../../shared/Utils';
export const QrLoginGuards={
export const QrLoginGuards = {
showFaceAuthConsentScreen: context => {
return context.showFaceAuthConsent;
},
return context.showFaceAuthConsent;
},
isConsentAlreadyCaptured: (_, event) =>
event.data?.consentAction === 'NOCAPTURE',
isConsentAlreadyCaptured: (_, event) =>
event.data?.consentAction === 'NOCAPTURE',
isSimpleShareFlow: (context, _event) =>
context.flowType === VCShareFlowType.SIMPLE_SHARE,
}
isSimpleShareFlow: (context, _event) =>
context.flowType === VCShareFlowType.SIMPLE_SHARE,
};

View File

@@ -1,17 +1,14 @@
import {
ActorRefFrom,
EventFrom
} from 'xstate';
import { AppServices } from '../../shared/GlobalContext';
import { TelemetryConstants } from '../../shared/telemetry/TelemetryConstants';
import {ActorRefFrom, EventFrom} from 'xstate';
import {AppServices} from '../../shared/GlobalContext';
import {TelemetryConstants} from '../../shared/telemetry/TelemetryConstants';
import {
getEndEventData,
sendEndEvent,
} from '../../shared/telemetry/TelemetryUtils';
import { QrLoginActions } from './QrLoginActions';
import { QrLoginmodel } from './QrLoginModel';
import { QrLoginServices } from './QrLoginServices';
import { QrLoginGuards } from './QrLoginGuards';
import {QrLoginActions} from './QrLoginActions';
import {QrLoginmodel} from './QrLoginModel';
import {QrLoginServices} from './QrLoginServices';
import {QrLoginGuards} from './QrLoginGuards';
const model = QrLoginmodel;
@@ -131,15 +128,16 @@ export const qrLoginMachine =
actions: ['storeShowFaceAuthConsent', 'setShowFaceAuthConsent'],
target: 'faceAuth',
},
DISMISS: [{
cond:'isSimpleShareFlow',
target: 'showvcList',
},
{
actions: 'forwardToParent',
target: 'waitingForData',
}
]
DISMISS: [
{
cond: 'isSimpleShareFlow',
target: 'showvcList',
},
{
actions: 'forwardToParent',
target: 'waitingForData',
},
],
},
},
faceAuth: {
@@ -173,7 +171,8 @@ export const qrLoginMachine =
actions: 'forwardToParent',
target: 'waitingForData',
},
,],
,
],
RETRY_VERIFICATION: {
target: 'faceAuth',
},
@@ -261,8 +260,8 @@ export const qrLoginMachine =
},
},
{
actions:QrLoginActions(model),
services:QrLoginServices,
actions: QrLoginActions(model),
services: QrLoginServices,
guards: QrLoginGuards,
},
);
@@ -273,5 +272,3 @@ export function createQrLoginMachine(serviceRefs: AppServices) {
serviceRefs,
});
}

View File

@@ -1,64 +1,124 @@
// This file was automatically generated. Edits will be overwritten
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"done.invoke.QrLogin.linkTransaction:invocation[0]": { type: "done.invoke.QrLogin.linkTransaction:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.QrLogin.sendingAuthenticate:invocation[0]": { type: "done.invoke.QrLogin.sendingAuthenticate:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"error.platform.QrLogin.linkTransaction:invocation[0]": { type: "error.platform.QrLogin.linkTransaction:invocation[0]"; data: unknown };
"error.platform.QrLogin.sendingAuthenticate:invocation[0]": { type: "error.platform.QrLogin.sendingAuthenticate:invocation[0]"; data: unknown };
"error.platform.QrLogin.sendingConsent:invocation[0]": { type: "error.platform.QrLogin.sendingConsent:invocation[0]"; data: unknown };
"xstate.init": { type: "xstate.init" };
};
invokeSrcNameMap: {
"linkTransaction": "done.invoke.QrLogin.linkTransaction:invocation[0]";
"sendAuthenticate": "done.invoke.QrLogin.sendingAuthenticate:invocation[0]";
"sendConsent": "done.invoke.QrLogin.sendingConsent:invocation[0]";
};
missingImplementations: {
actions: "SetErrorMessage" | "expandLinkTransResp" | "forwardToParent" | "getFaceAuthConsent" | "loadMyVcs" | "loadThumbprint" | "resetFlowType" | "resetLinkTransactionId" | "resetSelectedVc" | "resetSelectedVoluntaryClaims" | "setClaims" | "setConsentClaims" | "setLinkedTransactionId" | "setMyVcs" | "setScanData" | "setSelectedVc" | "setShowFaceAuthConsent" | "setThumbprint" | "setlinkTransactionResponse" | "storeShowFaceAuthConsent" | "updateShowFaceAuthConsent";
delays: never;
guards: "isConsentAlreadyCaptured" | "isSimpleShareFlow" | "showFaceAuthConsentScreen";
services: "linkTransaction" | "sendAuthenticate" | "sendConsent";
};
eventsCausingActions: {
"SetErrorMessage": "error.platform.QrLogin.linkTransaction:invocation[0]" | "error.platform.QrLogin.sendingAuthenticate:invocation[0]" | "error.platform.QrLogin.sendingConsent:invocation[0]";
"expandLinkTransResp": "done.invoke.QrLogin.linkTransaction:invocation[0]";
"forwardToParent": "CANCEL" | "DISMISS";
"getFaceAuthConsent": "GET";
"loadMyVcs": "done.invoke.QrLogin.linkTransaction:invocation[0]";
"loadThumbprint": "FACE_VALID";
"resetFlowType": "xstate.init";
"resetLinkTransactionId": "GET";
"resetSelectedVc": "xstate.init";
"resetSelectedVoluntaryClaims": "GET";
"setClaims": "done.invoke.QrLogin.linkTransaction:invocation[0]";
"setConsentClaims": "TOGGLE_CONSENT_CLAIM";
"setLinkedTransactionId": "done.invoke.QrLogin.sendingAuthenticate:invocation[0]";
"setMyVcs": "STORE_RESPONSE";
"setScanData": "GET";
"setSelectedVc": "SELECT_VC";
"setShowFaceAuthConsent": "FACE_VERIFICATION_CONSENT";
"setThumbprint": "STORE_RESPONSE";
"setlinkTransactionResponse": "done.invoke.QrLogin.linkTransaction:invocation[0]";
"storeShowFaceAuthConsent": "FACE_VERIFICATION_CONSENT";
"updateShowFaceAuthConsent": "STORE_RESPONSE";
};
eventsCausingDelays: {
};
eventsCausingGuards: {
"isConsentAlreadyCaptured": "done.invoke.QrLogin.sendingAuthenticate:invocation[0]";
"isSimpleShareFlow": "CANCEL" | "DISMISS" | "done.invoke.QrLogin.linkTransaction:invocation[0]";
"showFaceAuthConsentScreen": "VERIFY" | "done.invoke.QrLogin.linkTransaction:invocation[0]";
};
eventsCausingServices: {
"linkTransaction": "STORE_RESPONSE";
"sendAuthenticate": "STORE_RESPONSE";
"sendConsent": "CONFIRM";
};
matchesStates: "ShowError" | "checkFaceAuthConsent" | "done" | "faceAuth" | "faceVerificationConsent" | "invalidIdentity" | "linkTransaction" | "loadMyVcs" | "loadingThumbprint" | "requestConsent" | "sendingAuthenticate" | "sendingConsent" | "showvcList" | "success" | "waitingForData";
tags: never;
}
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'done.invoke.QrLogin.linkTransaction:invocation[0]': {
type: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.QrLogin.sendingAuthenticate:invocation[0]': {
type: 'done.invoke.QrLogin.sendingAuthenticate:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'error.platform.QrLogin.linkTransaction:invocation[0]': {
type: 'error.platform.QrLogin.linkTransaction:invocation[0]';
data: unknown;
};
'error.platform.QrLogin.sendingAuthenticate:invocation[0]': {
type: 'error.platform.QrLogin.sendingAuthenticate:invocation[0]';
data: unknown;
};
'error.platform.QrLogin.sendingConsent:invocation[0]': {
type: 'error.platform.QrLogin.sendingConsent:invocation[0]';
data: unknown;
};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
linkTransaction: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
sendAuthenticate: 'done.invoke.QrLogin.sendingAuthenticate:invocation[0]';
sendConsent: 'done.invoke.QrLogin.sendingConsent:invocation[0]';
};
missingImplementations: {
actions:
| 'SetErrorMessage'
| 'expandLinkTransResp'
| 'forwardToParent'
| 'getFaceAuthConsent'
| 'loadMyVcs'
| 'loadThumbprint'
| 'resetFlowType'
| 'resetLinkTransactionId'
| 'resetSelectedVc'
| 'resetSelectedVoluntaryClaims'
| 'setClaims'
| 'setConsentClaims'
| 'setLinkedTransactionId'
| 'setMyVcs'
| 'setScanData'
| 'setSelectedVc'
| 'setShowFaceAuthConsent'
| 'setThumbprint'
| 'setlinkTransactionResponse'
| 'storeShowFaceAuthConsent'
| 'updateShowFaceAuthConsent';
delays: never;
guards:
| 'isConsentAlreadyCaptured'
| 'isSimpleShareFlow'
| 'showFaceAuthConsentScreen';
services: 'linkTransaction' | 'sendAuthenticate' | 'sendConsent';
};
eventsCausingActions: {
SetErrorMessage:
| 'error.platform.QrLogin.linkTransaction:invocation[0]'
| 'error.platform.QrLogin.sendingAuthenticate:invocation[0]'
| 'error.platform.QrLogin.sendingConsent:invocation[0]';
expandLinkTransResp: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
forwardToParent: 'CANCEL' | 'DISMISS';
getFaceAuthConsent: 'GET';
loadMyVcs: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
loadThumbprint: 'FACE_VALID';
resetFlowType: 'xstate.init';
resetLinkTransactionId: 'GET';
resetSelectedVc: 'xstate.init';
resetSelectedVoluntaryClaims: 'GET';
setClaims: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
setConsentClaims: 'TOGGLE_CONSENT_CLAIM';
setLinkedTransactionId: 'done.invoke.QrLogin.sendingAuthenticate:invocation[0]';
setMyVcs: 'STORE_RESPONSE';
setScanData: 'GET';
setSelectedVc: 'SELECT_VC';
setShowFaceAuthConsent: 'FACE_VERIFICATION_CONSENT';
setThumbprint: 'STORE_RESPONSE';
setlinkTransactionResponse: 'done.invoke.QrLogin.linkTransaction:invocation[0]';
storeShowFaceAuthConsent: 'FACE_VERIFICATION_CONSENT';
updateShowFaceAuthConsent: 'STORE_RESPONSE';
};
eventsCausingDelays: {};
eventsCausingGuards: {
isConsentAlreadyCaptured: 'done.invoke.QrLogin.sendingAuthenticate:invocation[0]';
isSimpleShareFlow:
| 'CANCEL'
| 'DISMISS'
| 'done.invoke.QrLogin.linkTransaction:invocation[0]';
showFaceAuthConsentScreen:
| 'VERIFY'
| 'done.invoke.QrLogin.linkTransaction:invocation[0]';
};
eventsCausingServices: {
linkTransaction: 'STORE_RESPONSE';
sendAuthenticate: 'STORE_RESPONSE';
sendConsent: 'CONFIRM';
};
matchesStates:
| 'ShowError'
| 'checkFaceAuthConsent'
| 'done'
| 'faceAuth'
| 'faceVerificationConsent'
| 'invalidIdentity'
| 'linkTransaction'
| 'loadMyVcs'
| 'loadingThumbprint'
| 'requestConsent'
| 'sendingAuthenticate'
| 'sendingConsent'
| 'showvcList'
| 'success'
| 'waitingForData';
tags: never;
}

View File

@@ -1,10 +1,13 @@
import { createModel } from "xstate/lib/model";
import { AppServices } from "../../shared/GlobalContext";
import { VCShareFlowType } from "../../shared/Utils";
import { VCMetadata } from "../../shared/VCMetadata";
import { VC, linkTransactionResponse } from "../VerifiableCredential/VCMetaMachine/vc";
import {createModel} from 'xstate/lib/model';
import {AppServices} from '../../shared/GlobalContext';
import {VCShareFlowType} from '../../shared/Utils';
import {VCMetadata} from '../../shared/VCMetadata';
import {
VC,
linkTransactionResponse,
} from '../VerifiableCredential/VCMetaMachine/vc';
const QrLoginEvents= {
const QrLoginEvents = {
SELECT_VC: (vc: VC) => ({vc}),
SCANNING_DONE: (params: string) => ({params}),
STORE_RESPONSE: (response: unknown) => ({response}),
@@ -34,36 +37,34 @@ const QrLoginEvents= {
FACE_VERIFICATION_CONSENT: (isDoNotAskAgainChecked: boolean) => ({
isDoNotAskAgainChecked,
}),
}
};
export const QrLoginmodel = createModel(
{
serviceRefs: {} as AppServices,
selectedVc: {} as VC,
linkCode: '',
flowType: VCShareFlowType.SIMPLE_SHARE,
myVcs: [] as VCMetadata[],
thumbprint: '',
linkTransactionResponse: {} as linkTransactionResponse,
authFactors: [],
authorizeScopes: null,
clientName: {},
configs: {},
essentialClaims: [],
linkTransactionId: '',
logoUrl: '',
voluntaryClaims: [],
selectedVoluntaryClaims: [],
errorMessage: '',
domainName: '',
consentClaims: ['name', 'picture'],
isSharing: {},
linkedTransactionId: '',
showFaceAuthConsent: true as boolean,
},
{
events:QrLoginEvents,
},
);
{
serviceRefs: {} as AppServices,
selectedVc: {} as VC,
linkCode: '',
flowType: VCShareFlowType.SIMPLE_SHARE,
myVcs: [] as VCMetadata[],
thumbprint: '',
linkTransactionResponse: {} as linkTransactionResponse,
authFactors: [],
authorizeScopes: null,
clientName: {},
configs: {},
essentialClaims: [],
linkTransactionId: '',
logoUrl: '',
voluntaryClaims: [],
selectedVoluntaryClaims: [],
errorMessage: '',
domainName: '',
consentClaims: ['name', 'picture'],
isSharing: {},
linkedTransactionId: '',
showFaceAuthConsent: true as boolean,
},
{
events: QrLoginEvents,
},
);

View File

@@ -1,7 +1,7 @@
import { StateFrom } from "xstate";
import { getMosipLogo } from "../../components/VC/common/VCUtils";
import { VCMetadata } from "../../shared/VCMetadata";
import { qrLoginMachine } from "./QrLoginMachine";
import {StateFrom} from 'xstate';
import {getMosipLogo} from '../../components/VC/common/VCUtils';
import {VCMetadata} from '../../shared/VCMetadata';
import {qrLoginMachine} from './QrLoginMachine';
type State = StateFrom<typeof qrLoginMachine>;
@@ -114,4 +114,4 @@ export function selectIsSharing(state: State) {
export function selectIsFaceVerificationConsent(state: State) {
return state.matches('faceVerificationConsent');
}
}

View File

@@ -1,111 +1,114 @@
import {request} from '../../shared/request';
import getAllConfigurations, { API_URLS } from "../../shared/api";
import { ESIGNET_BASE_URL } from "../../shared/constants";
import { isHardwareKeystoreExists, getJWT } from "../../shared/cryptoutil/cryptoUtil";
import { getPrivateKey } from "../../shared/keystore/SecureKeystore";
import getAllConfigurations, {API_URLS} from '../../shared/api';
import {ESIGNET_BASE_URL} from '../../shared/constants';
import {
isHardwareKeystoreExists,
getJWT,
} from '../../shared/cryptoutil/cryptoUtil';
import {getPrivateKey} from '../../shared/keystore/SecureKeystore';
export const QrLoginServices= {
linkTransaction: async context => {
const response = await request(
API_URLS.linkTransaction.method,
API_URLS.linkTransaction.buildURL(),
{
requestTime: String(new Date().toISOString()),
request: {
linkCode: context.linkCode,
},
export const QrLoginServices = {
linkTransaction: async context => {
const response = await request(
API_URLS.linkTransaction.method,
API_URLS.linkTransaction.buildURL(),
{
requestTime: String(new Date().toISOString()),
request: {
linkCode: context.linkCode,
},
ESIGNET_BASE_URL,
},
ESIGNET_BASE_URL,
);
return response.response;
},
sendAuthenticate: async context => {
let privateKey;
const individualId = context.selectedVc.vcMetadata.id;
if (!isHardwareKeystoreExists) {
privateKey = await getPrivateKey(
context.selectedVc.walletBindingResponse?.walletBindingId,
);
return response.response;
},
}
sendAuthenticate: async context => {
let privateKey;
const individualId = context.selectedVc.vcMetadata.id;
if (!isHardwareKeystoreExists) {
privateKey = await getPrivateKey(
context.selectedVc.walletBindingResponse?.walletBindingId,
);
}
var config = await getAllConfigurations();
const header = {
alg: 'RS256',
'x5t#S256': context.thumbprint,
};
var config = await getAllConfigurations();
const header = {
alg: 'RS256',
'x5t#S256': context.thumbprint,
};
const payload = {
iss: config.issuer,
sub: individualId,
aud: config.audience,
iat: Math.floor(new Date().getTime() / 1000),
exp: Math.floor(new Date().getTime() / 1000) + 18000,
};
const payload = {
iss: config.issuer,
sub: individualId,
aud: config.audience,
iat: Math.floor(new Date().getTime() / 1000),
exp: Math.floor(new Date().getTime() / 1000) + 18000,
};
const jwt = await getJWT(header, payload, individualId, privateKey);
const jwt = await getJWT(header, payload, individualId, privateKey);
const response = await request(
API_URLS.authenticate.method,
API_URLS.authenticate.buildURL(),
{
requestTime: String(new Date().toISOString()),
request: {
linkedTransactionId: context.linkTransactionId,
individualId: individualId,
challengeList: [
{
authFactorType: 'WLA',
challenge: jwt,
format: 'jwt',
},
],
},
const response = await request(
API_URLS.authenticate.method,
API_URLS.authenticate.buildURL(),
{
requestTime: String(new Date().toISOString()),
request: {
linkedTransactionId: context.linkTransactionId,
individualId: individualId,
challengeList: [
{
authFactorType: 'WLA',
challenge: jwt,
format: 'jwt',
},
],
},
ESIGNET_BASE_URL,
},
ESIGNET_BASE_URL,
);
return response.response;
},
sendConsent: async context => {
let privateKey;
const individualId = context.selectedVc.vcMetadata.id;
if (!isHardwareKeystoreExists) {
privateKey = await getPrivateKey(
context.selectedVc.walletBindingResponse?.walletBindingId,
);
return response.response;
},
}
sendConsent: async context => {
let privateKey;
const individualId = context.selectedVc.vcMetadata.id;
if (!isHardwareKeystoreExists) {
privateKey = await getPrivateKey(
context.selectedVc.walletBindingResponse?.walletBindingId,
);
}
const header = {
alg: 'RS256',
'x5t#S256': context.thumbprint,
};
const payload = {
accepted_claims: context.essentialClaims
.concat(context.selectedVoluntaryClaims)
.sort(),
permitted_authorized_scopes: context.authorizeScopes,
};
const header = {
alg: 'RS256',
'x5t#S256': context.thumbprint,
};
const payload = {
accepted_claims: context.essentialClaims
.concat(context.selectedVoluntaryClaims)
.sort(),
permitted_authorized_scopes: context.authorizeScopes,
};
const JWT = await getJWT(header, payload, individualId, privateKey);
const jwtComponents = JWT.split('.');
const detachedSignature = jwtComponents[0] + '.' + jwtComponents[2];
const JWT = await getJWT(header, payload, individualId, privateKey);
const jwtComponents = JWT.split('.');
const detachedSignature = jwtComponents[0] + '.' + jwtComponents[2];
const resp = await request(
API_URLS.sendConsent.method,
API_URLS.sendConsent.buildURL(),
{
requestTime: String(new Date().toISOString()),
request: {
linkedTransactionId: context.linkedTransactionId,
acceptedClaims: context.essentialClaims
.concat(context.selectedVoluntaryClaims)
.sort(),
permittedAuthorizeScopes: context.authorizeScopes,
signature: detachedSignature,
},
const resp = await request(
API_URLS.sendConsent.method,
API_URLS.sendConsent.buildURL(),
{
requestTime: String(new Date().toISOString()),
request: {
linkedTransactionId: context.linkedTransactionId,
acceptedClaims: context.essentialClaims
.concat(context.selectedVoluntaryClaims)
.sort(),
permittedAuthorizeScopes: context.authorizeScopes,
signature: detachedSignature,
},
ESIGNET_BASE_URL,
);
},
}
},
ESIGNET_BASE_URL,
);
},
};

View File

@@ -9,7 +9,10 @@ import {getHomeMachineService} from '../../../screens/Home/HomeScreenController'
import {DownloadProps} from '../../../shared/api';
import {isHardwareKeystoreExists} from '../../../shared/cryptoutil/cryptoUtil';
import {getBindingCertificateConstant} from '../../../shared/keystore/SecureKeystore';
import {getIdType} from '../../../shared/openId4VCI/Utils';
import {
getIdType,
getVcVerificationDetails,
} from '../../../shared/openId4VCI/Utils';
import {TelemetryConstants} from '../../../shared/telemetry/TelemetryConstants';
import {
sendStartEvent,
@@ -26,9 +29,72 @@ import {ActivityLogEvents} from '../../activityLog';
import {BackupEvents} from '../../backupAndRestore/backup';
import {VcMetaEvents} from '../VCMetaMachine/VCMetaMachine';
import {WalletBindingResponse} from '../VCMetaMachine/vc';
import {BannerStatusType} from '../../../components/BannerNotification';
export const VCItemActions = model => {
return {
setIsVerified: assign({
vcMetadata: (context: any) =>
new VCMetadata({
...context.vcMetadata,
isVerified: true,
}),
}),
resetIsVerified: assign({
vcMetadata: (context: any) =>
new VCMetadata({
...context.vcMetadata,
isVerified: false,
}),
}),
setVerificationStatus: assign({
verificationStatus: (context: any, event) => {
const statusType =
event.response.statusType === BannerStatusType.IN_PROGRESS
? BannerStatusType.IN_PROGRESS
: event.response.vcMetadata.isVerified
? BannerStatusType.SUCCESS
: BannerStatusType.ERROR;
return getVcVerificationDetails(
statusType,
context.vcMetadata,
context.verifiableCredential,
);
},
}),
resetVerificationStatus: assign({
verificationStatus: (context: any) => {
return context.verificationStatus?.statusType ===
BannerStatusType.IN_PROGRESS
? context.verificationStatus
: null;
},
showVerificationStatusBanner: () => false,
}),
showVerificationBannerStatus: assign({
showVerificationStatusBanner: () => true,
}),
sendVerificationStatusToVcMeta: send(
(context: any) => ({
type: 'SET_VERIFICATION_STATUS',
verificationStatus: context.verificationStatus,
}),
{to: context => context.serviceRefs.vcMeta},
),
removeVerificationStatusFromVcMeta: send(
(context: any) => ({
type: 'RESET_VERIFICATION_STATUS',
verificationStatus: context.verificationStatus,
}),
{to: context => context.serviceRefs.vcMeta},
),
setCommunicationDetails: model.assign({
communicationDetails: (_context, event) => {
const communicationDetails: CommunicationDetails = {
@@ -66,7 +132,13 @@ export const VCItemActions = model => {
}),
storeContext: send(
(context: any) => {
const {serviceRefs, isMachineInKebabPopupState, ...data} = context;
const {
serviceRefs,
isMachineInKebabPopupState,
verificationStatus,
showVerificationStatusBanner,
...data
} = context;
data.credentialRegistry = MIMOTO_BASE_URL;
return StoreEvents.SET(
VCMetadata.fromVC(context.vcMetadata).getVcKey(),
@@ -94,6 +166,14 @@ export const VCItemActions = model => {
to: context => context.serviceRefs.vcMeta,
},
),
updateVcMetadata: send(
(context: any) => VcMetaEvents.VC_METADATA_UPDATED(context.vcMetadata),
{
to: (context: any) => context.serviceRefs.vcMeta,
},
),
removeVcMetaDataFromStorage: send(
(context: any) => {
return StoreEvents.REMOVE_VC_METADATA(
@@ -164,13 +244,7 @@ export const VCItemActions = model => {
sendBackupEvent: send(BackupEvents.DATA_BACKUP(true), {
to: (context: any) => context.serviceRefs.backup,
}),
//todo: revisit on this for naming and impl
sendVcUpdated: send(
(context: any) => VcMetaEvents.VC_METADATA_UPDATED(context.vcMetadata),
{
to: (context: any) => context.serviceRefs.vcMeta,
},
),
setErrorAsWalletBindingError: assign({
error: () =>
i18n.t('errors.genericError', {

View File

@@ -24,4 +24,9 @@ export const VCItemEvents = {
UPDATE_VC_METADATA: (vcMetadata: VCMetadata) => ({vcMetadata}),
TAMPERED_VC: (key: string) => ({key}),
SHOW_BINDING_STATUS: () => ({}),
VERIFY: () => ({}),
SET_VERIFICATION_STATUS: (response: unknown) => ({response}),
RESET_VERIFICATION_STATUS: () => ({}),
REMOVE_VERIFICATION_STATUS_BANNER: () => ({}),
SHOW_VERIFICATION_STATUS_BANNER: (response: unknown) => ({response}),
};

View File

@@ -1,5 +1,6 @@
import {isSignedInResult} from '../../../shared/CloudBackupAndRestoreUtils';
import {isHardwareKeystoreExists} from '../../../shared/cryptoutil/cryptoUtil';
import {VerificationErrorType} from '../../../shared/vcjs/verifyCredential';
export const VCItemGaurds = () => {
return {
@@ -15,5 +16,8 @@ export const VCItemGaurds = () => {
},
isCustomSecureKeystore: () => isHardwareKeystoreExists,
isPendingVerificationError: (_context, event) =>
(event.data as Error).message == VerificationErrorType.NETWORK_ERROR,
};
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,123 +1,450 @@
// This file was automatically generated. Edits will be overwritten
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"": { type: "" };
"done.invoke.checkStatus": { type: "done.invoke.checkStatus"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.downloadCredential": { type: "done.invoke.downloadCredential"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]": { type: "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]": { type: "done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]": { type: "done.invoke.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]": { type: "done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item-machine.verifyingCredential:invocation[0]": { type: "done.invoke.vc-item-machine.verifyingCredential:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]": { type: "done.invoke.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]": { type: "done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]": { type: "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]": { type: "done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]": { type: "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"error.platform.checkStatus": { type: "error.platform.checkStatus"; data: unknown };
"error.platform.downloadCredential": { type: "error.platform.downloadCredential"; data: unknown };
"error.platform.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]": { type: "error.platform.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]"; data: unknown };
"error.platform.vc-item-machine.verifyingCredential:invocation[0]": { type: "error.platform.vc-item-machine.verifyingCredential:invocation[0]"; data: unknown };
"error.platform.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]": { type: "error.platform.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]"; data: unknown };
"error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]": { type: "error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]"; data: unknown };
"error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]": { type: "error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]"; data: unknown };
"error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]": { type: "error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]"; data: unknown };
"error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]": { type: "error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]"; data: unknown };
"xstate.init": { type: "xstate.init" };
"xstate.stop": { type: "xstate.stop" };
};
invokeSrcNameMap: {
"addWalletBindingId": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]";
"checkDownloadExpiryLimit": "done.invoke.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]";
"checkStatus": "done.invoke.checkStatus";
"downloadCredential": "done.invoke.downloadCredential";
"generateKeyPair": "done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]";
"isUserSignedAlready": "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]" | "done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]";
"loadDownloadLimitConfig": "done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]";
"requestBindingOTP": "done.invoke.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]";
"updatePrivateKey": "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
"verifyCredential": "done.invoke.vc-item-machine.verifyingCredential:invocation[0]";
};
missingImplementations: {
actions: "addVcToInProgressDownloads" | "closeViewVcModal" | "incrementDownloadCounter" | "logDownloaded" | "logRemovedVc" | "logWalletBindingFailure" | "logWalletBindingSuccess" | "refreshAllVcs" | "removeVcFromInProgressDownloads" | "removeVcItem" | "removeVcMetaDataFromStorage" | "removeVcMetaDataFromVcMachineContext" | "requestVcContext" | "resetIsMachineInKebabPopupState" | "resetPrivateKey" | "sendActivationStartEvent" | "sendActivationSuccessEvent" | "sendBackupEvent" | "sendDownloadLimitExpire" | "sendTelemetryEvents" | "sendUserCancelledActivationFailedEndEvent" | "sendVcUpdated" | "sendVerificationError" | "sendWalletBindingErrorEvent" | "sendWalletBindingSuccess" | "setCommunicationDetails" | "setContext" | "setDownloadInterval" | "setErrorAsVerificationError" | "setErrorAsWalletBindingError" | "setMaxDownloadCount" | "setOTP" | "setPinCard" | "setPrivateKey" | "setPublicKey" | "setThumbprintForWalletBindingId" | "setVcKey" | "setVcMetadata" | "setWalletBindingResponse" | "storeContext" | "storeVcInContext" | "unSetBindingTransactionId" | "unSetError" | "unSetOTP";
delays: never;
guards: "hasCredential" | "isCustomSecureKeystore" | "isDownloadAllowed" | "isSignedIn";
services: "addWalletBindingId" | "checkDownloadExpiryLimit" | "checkStatus" | "downloadCredential" | "generateKeyPair" | "isUserSignedAlready" | "loadDownloadLimitConfig" | "requestBindingOTP" | "updatePrivateKey" | "verifyCredential";
};
eventsCausingActions: {
"addVcToInProgressDownloads": "GET_VC_RESPONSE";
"closeViewVcModal": "CLOSE_VC_MODAL" | "STORE_RESPONSE";
"incrementDownloadCounter": "POLL" | "done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]";
"logDownloaded": "STORE_RESPONSE";
"logRemovedVc": "STORE_RESPONSE" | "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]";
"logWalletBindingFailure": "error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]" | "error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]" | "error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
"logWalletBindingSuccess": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
"refreshAllVcs": "STORE_RESPONSE" | "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]";
"removeVcFromInProgressDownloads": "STORE_RESPONSE";
"removeVcItem": "CONFIRM";
"removeVcMetaDataFromStorage": "STORE_ERROR" | "error.platform.vc-item-machine.verifyingCredential:invocation[0]";
"removeVcMetaDataFromVcMachineContext": "DISMISS";
"requestVcContext": "DISMISS" | "REFRESH" | "STORE_ERROR" | "xstate.init";
"resetIsMachineInKebabPopupState": "" | "ADD_WALLET_BINDING_ID" | "CANCEL" | "CLOSE_VC_MODAL" | "DISMISS" | "REFRESH" | "REMOVE" | "SHOW_ACTIVITY" | "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]" | "xstate.stop";
"resetPrivateKey": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
"sendActivationStartEvent": "CONFIRM";
"sendActivationSuccessEvent": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
"sendBackupEvent": "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]" | "done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]";
"sendDownloadLimitExpire": "FAILED" | "error.platform.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]";
"sendTelemetryEvents": "STORE_RESPONSE";
"sendUserCancelledActivationFailedEndEvent": "DISMISS";
"sendVcUpdated": "PIN_CARD";
"sendVerificationError": "STORE_RESPONSE";
"sendWalletBindingErrorEvent": "error.platform.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]" | "error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]" | "error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]" | "error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
"sendWalletBindingSuccess": "SHOW_BINDING_STATUS";
"setCommunicationDetails": "done.invoke.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]";
"setContext": "CREDENTIAL_DOWNLOADED" | "GET_VC_RESPONSE";
"setDownloadInterval": "done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]";
"setErrorAsVerificationError": "error.platform.vc-item-machine.verifyingCredential:invocation[0]";
"setErrorAsWalletBindingError": "error.platform.vc-item-machine.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]" | "error.platform.vc-item-machine.walletBinding.addKeyPair:invocation[0]" | "error.platform.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "error.platform.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]" | "error.platform.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
"setMaxDownloadCount": "done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]";
"setOTP": "INPUT_OTP";
"setPinCard": "PIN_CARD";
"setPrivateKey": "done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]";
"setPublicKey": "done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]";
"setThumbprintForWalletBindingId": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
"setVcKey": "REMOVE";
"setVcMetadata": "UPDATE_VC_METADATA";
"setWalletBindingResponse": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]";
"storeContext": "done.invoke.vc-item-machine.verifyingCredential:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
"storeVcInContext": "STORE_RESPONSE" | "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
"unSetBindingTransactionId": "DISMISS";
"unSetError": "CANCEL" | "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.updatingPrivateKey:invocation[0]";
"unSetOTP": "DISMISS" | "done.invoke.vc-item-machine.walletBinding.requestingBindingOTP:invocation[0]";
};
eventsCausingDelays: {
};
eventsCausingGuards: {
"hasCredential": "GET_VC_RESPONSE";
"isCustomSecureKeystore": "done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]" | "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]";
"isDownloadAllowed": "POLL";
"isSignedIn": "done.invoke.vc-item-machine.kebabPopUp.triggerAutoBackup:invocation[0]" | "done.invoke.vc-item-machine.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]";
};
eventsCausingServices: {
"addWalletBindingId": "done.invoke.vc-item-machine.walletBinding.addKeyPair:invocation[0]";
"checkDownloadExpiryLimit": "POLL" | "done.invoke.vc-item-machine.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]";
"checkStatus": "done.invoke.vc-item-machine.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]";
"downloadCredential": "DOWNLOAD_READY";
"generateKeyPair": "INPUT_OTP";
"isUserSignedAlready": "STORE_RESPONSE";
"loadDownloadLimitConfig": "GET_VC_RESPONSE" | "STORE_ERROR";
"requestBindingOTP": "CONFIRM" | "RESEND_OTP";
"updatePrivateKey": "done.invoke.vc-item-machine.walletBinding.addingWalletBindingId:invocation[0]";
"verifyCredential": "CREDENTIAL_DOWNLOADED";
};
matchesStates: "idle" | "kebabPopUp" | "kebabPopUp.idle" | "kebabPopUp.pinCard" | "kebabPopUp.removeWallet" | "kebabPopUp.removingVc" | "kebabPopUp.showActivities" | "kebabPopUp.triggerAutoBackup" | "loadVc" | "loadVc.loadVcFromContext" | "loadVc.loadVcFromServer" | "loadVc.loadVcFromServer.checkingStatus" | "loadVc.loadVcFromServer.downloadingCredential" | "loadVc.loadVcFromServer.loadDownloadLimitConfig" | "loadVc.loadVcFromServer.savingFailed" | "loadVc.loadVcFromServer.savingFailed.idle" | "loadVc.loadVcFromServer.savingFailed.viewingVc" | "loadVc.loadVcFromServer.verifyingDownloadLimitExpiry" | "verifyingCredential" | "verifyingCredential.handleVCVerificationFailure" | "verifyingCredential.idle" | "verifyingCredential.triggerAutoBackupForVcDownload" | "walletBinding" | "walletBinding.acceptingBindingOTP" | "walletBinding.acceptingBindingOTP.idle" | "walletBinding.acceptingBindingOTP.resendOTP" | "walletBinding.addKeyPair" | "walletBinding.addingWalletBindingId" | "walletBinding.requestingBindingOTP" | "walletBinding.showBindingWarning" | "walletBinding.showingWalletBindingError" | "walletBinding.updatingContextVariables" | "walletBinding.updatingPrivateKey" | { "kebabPopUp"?: "idle" | "pinCard" | "removeWallet" | "removingVc" | "showActivities" | "triggerAutoBackup";
"loadVc"?: "loadVcFromContext" | "loadVcFromServer" | { "loadVcFromServer"?: "checkingStatus" | "downloadingCredential" | "loadDownloadLimitConfig" | "savingFailed" | "verifyingDownloadLimitExpiry" | { "savingFailed"?: "idle" | "viewingVc"; }; };
"verifyingCredential"?: "handleVCVerificationFailure" | "idle" | "triggerAutoBackupForVcDownload";
"walletBinding"?: "acceptingBindingOTP" | "addKeyPair" | "addingWalletBindingId" | "requestingBindingOTP" | "showBindingWarning" | "showingWalletBindingError" | "updatingContextVariables" | "updatingPrivateKey" | { "acceptingBindingOTP"?: "idle" | "resendOTP"; }; };
tags: never;
}
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'': {type: ''};
'done.invoke.checkStatus': {
type: 'done.invoke.checkStatus';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.downloadCredential': {
type: 'done.invoke.downloadCredential';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-machine.vcUtilitiesState.kebabPopUp.triggerAutoBackup:invocation[0]': {
type: 'done.invoke.vc-item-machine.vcUtilitiesState.kebabPopUp.triggerAutoBackup:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]': {
type: 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]': {
type: 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-machine.vcUtilitiesState.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]': {
type: 'done.invoke.vc-item-machine.vcUtilitiesState.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-machine.vcUtilitiesState.verifyingCredential:invocation[0]': {
type: 'done.invoke.vc-item-machine.vcUtilitiesState.verifyingCredential:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]': {
type: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]': {
type: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]': {
type: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.requestingBindingOTP:invocation[0]': {
type: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.requestingBindingOTP:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]': {
type: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.vc-item-machine.verifyState.verifyingCredential:invocation[0]': {
type: 'done.invoke.vc-item-machine.verifyState.verifyingCredential:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'error.platform.checkStatus': {
type: 'error.platform.checkStatus';
data: unknown;
};
'error.platform.downloadCredential': {
type: 'error.platform.downloadCredential';
data: unknown;
};
'error.platform.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]': {
type: 'error.platform.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]';
data: unknown;
};
'error.platform.vc-item-machine.vcUtilitiesState.verifyingCredential:invocation[0]': {
type: 'error.platform.vc-item-machine.vcUtilitiesState.verifyingCredential:invocation[0]';
data: unknown;
};
'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]': {
type: 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]';
data: unknown;
};
'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]': {
type: 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]';
data: unknown;
};
'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]': {
type: 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]';
data: unknown;
};
'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.requestingBindingOTP:invocation[0]': {
type: 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.requestingBindingOTP:invocation[0]';
data: unknown;
};
'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]': {
type: 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]';
data: unknown;
};
'error.platform.vc-item-machine.verifyState.verifyingCredential:invocation[0]': {
type: 'error.platform.vc-item-machine.verifyState.verifyingCredential:invocation[0]';
data: unknown;
};
'xstate.after(500)#vc-item-machine.verifyState.verifyingCredential': {
type: 'xstate.after(500)#vc-item-machine.verifyState.verifyingCredential';
};
'xstate.init': {type: 'xstate.init'};
'xstate.stop': {type: 'xstate.stop'};
};
invokeSrcNameMap: {
addWalletBindingId: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]';
checkDownloadExpiryLimit: 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]';
checkStatus: 'done.invoke.checkStatus';
downloadCredential: 'done.invoke.downloadCredential';
generateKeyPair: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]';
isUserSignedAlready:
| 'done.invoke.vc-item-machine.vcUtilitiesState.kebabPopUp.triggerAutoBackup:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]';
loadDownloadLimitConfig: 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]';
requestBindingOTP:
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.requestingBindingOTP:invocation[0]';
updatePrivateKey: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]';
verifyCredential:
| 'done.invoke.vc-item-machine.vcUtilitiesState.verifyingCredential:invocation[0]'
| 'done.invoke.vc-item-machine.verifyState.verifyingCredential:invocation[0]';
};
missingImplementations: {
actions:
| 'addVcToInProgressDownloads'
| 'closeViewVcModal'
| 'incrementDownloadCounter'
| 'logDownloaded'
| 'logRemovedVc'
| 'logWalletBindingFailure'
| 'logWalletBindingSuccess'
| 'refreshAllVcs'
| 'removeVcFromInProgressDownloads'
| 'removeVcItem'
| 'removeVcMetaDataFromStorage'
| 'removeVcMetaDataFromVcMachineContext'
| 'removeVerificationStatusFromVcMeta'
| 'requestVcContext'
| 'resetIsMachineInKebabPopupState'
| 'resetIsVerified'
| 'resetPrivateKey'
| 'resetVerificationStatus'
| 'sendActivationStartEvent'
| 'sendActivationSuccessEvent'
| 'sendBackupEvent'
| 'sendDownloadLimitExpire'
| 'sendDownloadingFailedToVcMeta'
| 'sendTelemetryEvents'
| 'sendUserCancelledActivationFailedEndEvent'
| 'sendVerificationError'
| 'sendVerificationStatusToVcMeta'
| 'sendWalletBindingErrorEvent'
| 'sendWalletBindingSuccess'
| 'setCommunicationDetails'
| 'setContext'
| 'setDownloadInterval'
| 'setErrorAsVerificationError'
| 'setErrorAsWalletBindingError'
| 'setIsVerified'
| 'setMaxDownloadCount'
| 'setOTP'
| 'setPinCard'
| 'setPrivateKey'
| 'setPublicKey'
| 'setThumbprintForWalletBindingId'
| 'setVcKey'
| 'setVcMetadata'
| 'setVerificationStatus'
| 'setWalletBindingResponse'
| 'showVerificationBannerStatus'
| 'storeContext'
| 'storeVcInContext'
| 'unSetBindingTransactionId'
| 'unSetError'
| 'unSetOTP'
| 'updateVcMetadata';
delays: never;
guards:
| 'hasCredential'
| 'isCustomSecureKeystore'
| 'isDownloadAllowed'
| 'isPendingVerificationError'
| 'isSignedIn';
services:
| 'addWalletBindingId'
| 'checkDownloadExpiryLimit'
| 'checkStatus'
| 'downloadCredential'
| 'generateKeyPair'
| 'isUserSignedAlready'
| 'loadDownloadLimitConfig'
| 'requestBindingOTP'
| 'updatePrivateKey'
| 'verifyCredential';
};
eventsCausingActions: {
addVcToInProgressDownloads: 'GET_VC_RESPONSE';
closeViewVcModal: 'CLOSE_VC_MODAL' | 'STORE_RESPONSE';
incrementDownloadCounter:
| 'POLL'
| 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]';
logDownloaded: 'STORE_RESPONSE';
logRemovedVc:
| 'STORE_RESPONSE'
| 'done.invoke.vc-item-machine.vcUtilitiesState.kebabPopUp.triggerAutoBackup:invocation[0]';
logWalletBindingFailure:
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]'
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]'
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.requestingBindingOTP:invocation[0]'
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]';
logWalletBindingSuccess:
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]';
refreshAllVcs:
| 'STORE_RESPONSE'
| 'done.invoke.vc-item-machine.vcUtilitiesState.kebabPopUp.triggerAutoBackup:invocation[0]';
removeVcFromInProgressDownloads:
| 'STORE_RESPONSE'
| 'error.platform.downloadCredential'
| 'error.platform.vc-item-machine.vcUtilitiesState.verifyingCredential:invocation[0]';
removeVcItem: 'CONFIRM';
removeVcMetaDataFromStorage:
| 'STORE_ERROR'
| 'error.platform.vc-item-machine.vcUtilitiesState.verifyingCredential:invocation[0]';
removeVcMetaDataFromVcMachineContext: 'DISMISS';
removeVerificationStatusFromVcMeta: 'RESET_VERIFICATION_STATUS';
requestVcContext: 'DISMISS' | 'REFRESH' | 'STORE_ERROR' | 'xstate.init';
resetIsMachineInKebabPopupState:
| ''
| 'ADD_WALLET_BINDING_ID'
| 'CANCEL'
| 'CLOSE_VC_MODAL'
| 'DISMISS'
| 'REFRESH'
| 'REMOVE'
| 'SHOW_ACTIVITY'
| 'done.invoke.vc-item-machine.vcUtilitiesState.kebabPopUp.triggerAutoBackup:invocation[0]'
| 'xstate.stop';
resetIsVerified:
| 'error.platform.vc-item-machine.vcUtilitiesState.verifyingCredential:invocation[0]'
| 'error.platform.vc-item-machine.verifyState.verifyingCredential:invocation[0]';
resetPrivateKey:
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]';
resetVerificationStatus:
| 'REMOVE_VERIFICATION_STATUS_BANNER'
| 'RESET_VERIFICATION_STATUS';
sendActivationStartEvent: 'CONFIRM';
sendActivationSuccessEvent:
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]';
sendBackupEvent:
| 'done.invoke.vc-item-machine.vcUtilitiesState.kebabPopUp.triggerAutoBackup:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]';
sendDownloadLimitExpire:
| 'FAILED'
| 'error.platform.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]';
sendDownloadingFailedToVcMeta: 'error.platform.downloadCredential';
sendTelemetryEvents: 'STORE_RESPONSE';
sendUserCancelledActivationFailedEndEvent: 'DISMISS';
sendVerificationError: 'STORE_RESPONSE';
sendVerificationStatusToVcMeta: 'STORE_RESPONSE';
sendWalletBindingErrorEvent:
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]'
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]'
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]'
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.requestingBindingOTP:invocation[0]'
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]';
sendWalletBindingSuccess: 'SHOW_BINDING_STATUS';
setCommunicationDetails:
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.requestingBindingOTP:invocation[0]';
setContext: 'CREDENTIAL_DOWNLOADED' | 'GET_VC_RESPONSE';
setDownloadInterval: 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]';
setErrorAsVerificationError: 'error.platform.vc-item-machine.vcUtilitiesState.verifyingCredential:invocation[0]';
setErrorAsWalletBindingError:
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.acceptingBindingOTP.resendOTP:invocation[0]'
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]'
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]'
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.requestingBindingOTP:invocation[0]'
| 'error.platform.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]';
setIsVerified:
| 'done.invoke.vc-item-machine.vcUtilitiesState.verifyingCredential:invocation[0]'
| 'done.invoke.vc-item-machine.verifyState.verifyingCredential:invocation[0]';
setMaxDownloadCount: 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]';
setOTP: 'INPUT_OTP';
setPinCard: 'PIN_CARD';
setPrivateKey: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]';
setPublicKey: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]';
setThumbprintForWalletBindingId:
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]';
setVcKey: 'REMOVE';
setVcMetadata: 'UPDATE_VC_METADATA';
setVerificationStatus:
| 'SET_VERIFICATION_STATUS'
| 'SHOW_VERIFICATION_STATUS_BANNER'
| 'STORE_RESPONSE';
setWalletBindingResponse: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]';
showVerificationBannerStatus:
| 'SHOW_VERIFICATION_STATUS_BANNER'
| 'STORE_RESPONSE'
| 'xstate.after(500)#vc-item-machine.verifyState.verifyingCredential';
storeContext:
| 'done.invoke.vc-item-machine.vcUtilitiesState.verifyingCredential:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]'
| 'done.invoke.vc-item-machine.verifyState.verifyingCredential:invocation[0]'
| 'error.platform.vc-item-machine.vcUtilitiesState.verifyingCredential:invocation[0]'
| 'error.platform.vc-item-machine.verifyState.verifyingCredential:invocation[0]';
storeVcInContext:
| 'STORE_RESPONSE'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]';
unSetBindingTransactionId: 'DISMISS';
unSetError:
| 'CANCEL'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.updatingPrivateKey:invocation[0]';
unSetOTP:
| 'DISMISS'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.requestingBindingOTP:invocation[0]';
updateVcMetadata: 'PIN_CARD' | 'STORE_RESPONSE';
};
eventsCausingDelays: {};
eventsCausingGuards: {
hasCredential: 'GET_VC_RESPONSE';
isCustomSecureKeystore:
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]';
isDownloadAllowed: 'POLL';
isPendingVerificationError:
| 'error.platform.vc-item-machine.vcUtilitiesState.verifyingCredential:invocation[0]'
| 'error.platform.vc-item-machine.verifyState.verifyingCredential:invocation[0]';
isSignedIn:
| 'done.invoke.vc-item-machine.vcUtilitiesState.kebabPopUp.triggerAutoBackup:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.verifyingCredential.triggerAutoBackupForVcDownload:invocation[0]';
};
eventsCausingServices: {
addWalletBindingId: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]';
checkDownloadExpiryLimit:
| 'POLL'
| 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.loadDownloadLimitConfig:invocation[0]';
checkStatus: 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]';
downloadCredential: 'DOWNLOAD_READY';
generateKeyPair: 'INPUT_OTP';
isUserSignedAlready: 'STORE_RESPONSE';
loadDownloadLimitConfig: 'GET_VC_RESPONSE' | 'STORE_ERROR';
requestBindingOTP: 'CONFIRM' | 'RESEND_OTP';
updatePrivateKey: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]';
verifyCredential: 'CREDENTIAL_DOWNLOADED' | 'VERIFY';
};
matchesStates:
| 'vcUtilitiesState'
| 'vcUtilitiesState.idle'
| 'vcUtilitiesState.kebabPopUp'
| 'vcUtilitiesState.kebabPopUp.idle'
| 'vcUtilitiesState.kebabPopUp.pinCard'
| 'vcUtilitiesState.kebabPopUp.removeWallet'
| 'vcUtilitiesState.kebabPopUp.removingVc'
| 'vcUtilitiesState.kebabPopUp.showActivities'
| 'vcUtilitiesState.kebabPopUp.triggerAutoBackup'
| 'vcUtilitiesState.loadVc'
| 'vcUtilitiesState.loadVc.loadVcFromContext'
| 'vcUtilitiesState.loadVc.loadVcFromServer'
| 'vcUtilitiesState.loadVc.loadVcFromServer.checkingStatus'
| 'vcUtilitiesState.loadVc.loadVcFromServer.downloadingCredential'
| 'vcUtilitiesState.loadVc.loadVcFromServer.loadDownloadLimitConfig'
| 'vcUtilitiesState.loadVc.loadVcFromServer.savingFailed'
| 'vcUtilitiesState.loadVc.loadVcFromServer.savingFailed.idle'
| 'vcUtilitiesState.loadVc.loadVcFromServer.savingFailed.viewingVc'
| 'vcUtilitiesState.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry'
| 'vcUtilitiesState.verifyingCredential'
| 'vcUtilitiesState.verifyingCredential.handleVCVerificationFailure'
| 'vcUtilitiesState.verifyingCredential.idle'
| 'vcUtilitiesState.verifyingCredential.triggerAutoBackupForVcDownload'
| 'vcUtilitiesState.walletBinding'
| 'vcUtilitiesState.walletBinding.acceptingBindingOTP'
| 'vcUtilitiesState.walletBinding.acceptingBindingOTP.idle'
| 'vcUtilitiesState.walletBinding.acceptingBindingOTP.resendOTP'
| 'vcUtilitiesState.walletBinding.addKeyPair'
| 'vcUtilitiesState.walletBinding.addingWalletBindingId'
| 'vcUtilitiesState.walletBinding.requestingBindingOTP'
| 'vcUtilitiesState.walletBinding.showBindingWarning'
| 'vcUtilitiesState.walletBinding.showingWalletBindingError'
| 'vcUtilitiesState.walletBinding.updatingContextVariables'
| 'vcUtilitiesState.walletBinding.updatingPrivateKey'
| 'verifyState'
| 'verifyState.idle'
| 'verifyState.verificationCompleted'
| 'verifyState.verifyingCredential'
| {
vcUtilitiesState?:
| 'idle'
| 'kebabPopUp'
| 'loadVc'
| 'verifyingCredential'
| 'walletBinding'
| {
kebabPopUp?:
| 'idle'
| 'pinCard'
| 'removeWallet'
| 'removingVc'
| 'showActivities'
| 'triggerAutoBackup';
loadVc?:
| 'loadVcFromContext'
| 'loadVcFromServer'
| {
loadVcFromServer?:
| 'checkingStatus'
| 'downloadingCredential'
| 'loadDownloadLimitConfig'
| 'savingFailed'
| 'verifyingDownloadLimitExpiry'
| {savingFailed?: 'idle' | 'viewingVc'};
};
verifyingCredential?:
| 'handleVCVerificationFailure'
| 'idle'
| 'triggerAutoBackupForVcDownload';
walletBinding?:
| 'acceptingBindingOTP'
| 'addKeyPair'
| 'addingWalletBindingId'
| 'requestingBindingOTP'
| 'showBindingWarning'
| 'showingWalletBindingError'
| 'updatingContextVariables'
| 'updatingPrivateKey'
| {acceptingBindingOTP?: 'idle' | 'resendOTP'};
};
verifyState?: 'idle' | 'verificationCompleted' | 'verifyingCredential';
};
tags: never;
}

View File

@@ -4,6 +4,7 @@ import {VCMetadata} from '../../../shared/VCMetadata';
import {VerifiableCredential, WalletBindingResponse} from '../VCMetaMachine/vc';
import {CommunicationDetails} from '../../../shared/Utils';
import {VCItemEvents} from './VCItemEvents';
import {vcVerificationBannerDetails} from '../../../components/BannerNotificationContainer';
export const VCItemModel = createModel(
{
@@ -24,6 +25,8 @@ export const VCItemModel = createModel(
walletBindingResponse: null as unknown as WalletBindingResponse,
isMachineInKebabPopupState: false,
communicationDetails: null as unknown as CommunicationDetails,
verificationStatus: null as vcVerificationBannerDetails | null,
showVerificationStatusBanner: false as boolean,
},
{
events: VCItemEvents,

View File

@@ -5,14 +5,40 @@ import {getMosipLogo} from '../../../components/VC/common/VCUtils';
type State = StateFrom<typeof VCItemMachine>;
export function selectVerificationStatus(state: State) {
return state.context.verificationStatus;
}
export function selectIsVerificationInProgress(state: State) {
return state.matches('verifyState.verifyingCredential');
}
export function selectIsVerificationCompleted(state: State) {
return state.matches('verifyState.verificationCompleted');
}
export function selectShowVerificationStatusBanner(state: State) {
return state.context.showVerificationStatusBanner;
}
export function selectVerifiableCredential(state: State) {
return state.context.verifiableCredential;
}
export function getVerifiableCredential(
vcMetadata: VCMetadata,
verifiableCredential,
) {
return VCMetadata.fromVC(vcMetadata).isFromOpenId4VCI()
? verifiableCredential?.credential
: verifiableCredential;
}
export function selectCredential(state: State) {
return new VCMetadata(state.context.vcMetadata).isFromOpenId4VCI()
? state.context.verifiableCredential?.credential
: state.context.verifiableCredential;
return getVerifiableCredential(
state.context.vcMetadata,
state.context.verifiableCredential,
);
}
export function selectVerifiableCredentialData(state: State) {
@@ -68,24 +94,24 @@ export function selectBindingAuthFailedError(state: State) {
}
export function selectAcceptingBindingOtp(state: State) {
return state.matches('walletBinding.acceptingBindingOTP');
return state.matches('vcUtilitiesState.walletBinding.acceptingBindingOTP');
}
export function selectWalletBindingInProgress(state: State) {
return (
state.matches('walletBinding.requestingBindingOTP') ||
state.matches('walletBinding.addingWalletBindingId') ||
state.matches('walletBinding.addKeyPair') ||
state.matches('walletBinding.updatingPrivateKey')
state.matches('vcUtilitiesState.walletBinding.requestingBindingOTP') ||
state.matches('vcUtilitiesState.walletBinding.addingWalletBindingId') ||
state.matches('vcUtilitiesState.walletBinding.addKeyPair') ||
state.matches('vcUtilitiesState.walletBinding.updatingPrivateKey')
);
}
export function selectBindingWarning(state: State) {
return state.matches('walletBinding.showBindingWarning');
return state.matches('vcUtilitiesState.walletBinding.showBindingWarning');
}
export function selectRemoveWalletWarning(state: State) {
return state.matches('kebabPopUp.removeWallet');
return state.matches('vcUtilitiesState.kebabPopUp.removeWallet');
}
export function selectIsPinned(state: State) {
@@ -97,11 +123,13 @@ export function selectOtpError(state: State) {
}
export function selectShowActivities(state: State) {
return state.matches('kebabPopUp.showActivities');
return state.matches('vcUtilitiesState.kebabPopUp.showActivities');
}
export function selectShowWalletBindingError(state: State) {
return state.matches('walletBinding.showingWalletBindingError');
return state.matches(
'vcUtilitiesState.walletBinding.showingWalletBindingError',
);
}
export function selectVc(state: State) {

View File

@@ -9,14 +9,28 @@ import {
import {ActivityLogEvents} from '../../activityLog';
import {BackupEvents} from '../../backupAndRestore/backup';
import {StoreEvents} from '../../store';
import {vcVerificationBannerDetails} from '../../../components/BannerNotificationContainer';
export const VCMetaActions = (model: any) => {
return {
sendBackupEvent: send(BackupEvents.DATA_BACKUP(true), {
to: context => context.serviceRefs.backup,
resetVerificationStatus: model.assign({
verificationStatus: (context: any, event: any) =>
event.verificationStatus === null ||
context.verificationStatus === event.verificationStatus
? null
: context.verificationStatus,
}),
getVcItemResponse: respond((context, event) => {
setVerificationStatus: model.assign({
verificationStatus: (_, event) =>
event.verificationStatus as vcVerificationBannerDetails,
}),
sendBackupEvent: send(BackupEvents.DATA_BACKUP(true), {
to: (context: any) => context.serviceRefs.backup,
}),
getVcItemResponse: respond((context: any, event: any) => {
if (context.tamperedVcs.includes(event.vcMetadata)) {
return {
type: 'TAMPERED_VC',
@@ -140,10 +154,10 @@ export const VCMetaActions = (model: any) => {
}),
setUpdatedVcMetadatas: send(
_context => {
return StoreEvents.SET(MY_VCS_STORE_KEY, _context.myVcsMetadata);
(context: any) => {
return StoreEvents.SET(MY_VCS_STORE_KEY, context.myVcsMetadata);
},
{to: context => context.serviceRefs.store},
{to: (context: any) => context.serviceRefs.store},
),
prependToMyVcsMetadata: model.assign({
@@ -169,21 +183,21 @@ export const VCMetaActions = (model: any) => {
}),
removeDownloadFailedVcsFromStorage: send(
context => {
(context: any) => {
return StoreEvents.REMOVE_ITEMS(
MY_VCS_STORE_KEY,
context.downloadingFailedVcs.map(m => m.getVcKey()),
);
},
{
to: context => context.serviceRefs.store,
to: (context: any) => context.serviceRefs.store,
},
),
logTamperedVCsremoved: send(
context => ActivityLogEvents.LOG_ACTIVITY(ActivityLog.logTamperedVCs()),
{
to: context => context.serviceRefs.activityLog,
to: (context: any) => context.serviceRefs.activityLog,
},
),

View File

@@ -1,5 +1,6 @@
import {VCMetadata} from '../../../shared/VCMetadata';
import {VC} from './vc';
import {vcVerificationBannerDetails} from '../../../components/BannerNotificationContainer';
export const VcMetaEvents = {
VIEW_VC: (vc: VC) => ({vc}),
@@ -33,6 +34,14 @@ export const VcMetaEvents = {
RESET_VERIFY_ERROR: () => ({}),
REFRESH_VCS_METADATA: () => ({}),
SHOW_TAMPERED_POPUP: () => ({}),
SET_VERIFICATION_STATUS: (verificationStatus: unknown) => ({
verificationStatus,
}),
RESET_VERIFICATION_STATUS: (
verificationStatus: vcVerificationBannerDetails | null,
) => ({
verificationStatus,
}),
VC_DOWNLOADING_FAILED: () => ({}),
RESET_DOWNLOADING_FAILED: () => ({}),
};

View File

@@ -151,6 +151,12 @@ export const vcMetaMachine =
RESET_VERIFY_ERROR: {
actions: 'resetVerificationErrorMessage',
},
SET_VERIFICATION_STATUS: {
actions: 'setVerificationStatus',
},
RESET_VERIFICATION_STATUS: {
actions: 'resetVerificationStatus',
},
},
},
deletingFailedVcs: {

View File

@@ -1,58 +1,114 @@
// This file was automatically generated. Edits will be overwritten
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]": { type: "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"xstate.init": { type: "xstate.init" };
};
invokeSrcNameMap: {
"isUserSignedAlready": "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]";
};
missingImplementations: {
actions: "addVcToInProgressDownloads" | "getVcItemResponse" | "loadMyVcs" | "loadReceivedVcs" | "logTamperedVCsremoved" | "prependToMyVcsMetadata" | "removeDownloadFailedVcsFromStorage" | "removeDownloadingFailedVcsFromMyVcs" | "removeVcFromInProgressDownlods" | "removeVcFromMyVcsMetadata" | "resetDownloadFailedVcs" | "resetInProgressVcsDownloaded" | "resetTamperedVcs" | "resetVerificationErrorMessage" | "resetWalletBindingSuccess" | "sendBackupEvent" | "setDownloadedVc" | "setDownloadingFailedVcs" | "setMyVcs" | "setReceivedVcs" | "setUpdatedVcMetadatas" | "setVerificationErrorMessage" | "setWalletBindingSuccess" | "updateMyVcsMetadata";
delays: never;
guards: "isAnyVcTampered" | "isSignedIn";
services: "isUserSignedAlready";
};
eventsCausingActions: {
"addVcToInProgressDownloads": "ADD_VC_TO_IN_PROGRESS_DOWNLOADS";
"getVcItemResponse": "GET_VC_ITEM";
"loadMyVcs": "DOWNLOAD_LIMIT_EXPIRED" | "REFRESH_MY_VCS" | "REFRESH_RECEIVED_VCS" | "STORE_RESPONSE" | "VERIFY_VC_FAILED" | "xstate.init";
"loadReceivedVcs": "REFRESH_RECEIVED_VCS" | "STORE_RESPONSE";
"logTamperedVCsremoved": "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]";
"prependToMyVcsMetadata": "VC_ADDED";
"removeDownloadFailedVcsFromStorage": "DELETE_VC";
"removeDownloadingFailedVcsFromMyVcs": "STORE_RESPONSE";
"removeVcFromInProgressDownlods": "DOWNLOAD_LIMIT_EXPIRED" | "REMOVE_VC_FROM_IN_PROGRESS_DOWNLOADS" | "VERIFY_VC_FAILED";
"removeVcFromMyVcsMetadata": "REMOVE_VC_FROM_CONTEXT";
"resetDownloadFailedVcs": "STORE_RESPONSE";
"resetInProgressVcsDownloaded": "RESET_IN_PROGRESS_VCS_DOWNLOADED";
"resetTamperedVcs": "REMOVE_TAMPERED_VCS";
"resetVerificationErrorMessage": "RESET_VERIFY_ERROR";
"resetWalletBindingSuccess": "RESET_WALLET_BINDING_SUCCESS";
"sendBackupEvent": "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]";
"setDownloadedVc": "VC_DOWNLOADED";
"setDownloadingFailedVcs": "DOWNLOAD_LIMIT_EXPIRED";
"setMyVcs": "STORE_RESPONSE";
"setReceivedVcs": "STORE_RESPONSE";
"setUpdatedVcMetadatas": "VC_METADATA_UPDATED";
"setVerificationErrorMessage": "VERIFY_VC_FAILED";
"setWalletBindingSuccess": "WALLET_BINDING_SUCCESS";
"updateMyVcsMetadata": "VC_METADATA_UPDATED";
};
eventsCausingDelays: {
};
eventsCausingGuards: {
"isAnyVcTampered": "SHOW_TAMPERED_POPUP";
"isSignedIn": "done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]";
};
eventsCausingServices: {
"isUserSignedAlready": "REMOVE_TAMPERED_VCS";
};
matchesStates: "deletingFailedVcs" | "ready" | "ready.myVcs" | "ready.receivedVcs" | "ready.showTamperedPopup" | "ready.tamperedVCs" | "ready.tamperedVCs.idle" | "ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion" | { "ready"?: "myVcs" | "receivedVcs" | "showTamperedPopup" | "tamperedVCs" | { "tamperedVCs"?: "idle" | "triggerAutoBackupForTamperedVcDeletion"; }; };
tags: never;
}
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]': {
type: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
isUserSignedAlready: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
};
missingImplementations: {
actions:
| 'addVcToInProgressDownloads'
| 'getVcItemResponse'
| 'loadMyVcs'
| 'loadReceivedVcs'
| 'logTamperedVCsremoved'
| 'prependToMyVcsMetadata'
| 'removeDownloadFailedVcsFromStorage'
| 'removeDownloadingFailedVcsFromMyVcs'
| 'removeVcFromInProgressDownlods'
| 'removeVcFromMyVcsMetadata'
| 'resetDownloadCreadentialsFailed'
| 'resetDownloadFailedVcs'
| 'resetInProgressVcsDownloaded'
| 'resetTamperedVcs'
| 'resetVerificationErrorMessage'
| 'resetVerificationStatus'
| 'resetWalletBindingSuccess'
| 'sendBackupEvent'
| 'setDownloadCreadentialsFailed'
| 'setDownloadedVc'
| 'setDownloadingFailedVcs'
| 'setMyVcs'
| 'setReceivedVcs'
| 'setUpdatedVcMetadatas'
| 'setVerificationErrorMessage'
| 'setVerificationStatus'
| 'setWalletBindingSuccess'
| 'updateMyVcsMetadata';
delays: never;
guards: 'isAnyVcTampered' | 'isSignedIn';
services: 'isUserSignedAlready';
};
eventsCausingActions: {
addVcToInProgressDownloads: 'ADD_VC_TO_IN_PROGRESS_DOWNLOADS';
getVcItemResponse: 'GET_VC_ITEM';
loadMyVcs:
| 'REFRESH_MY_VCS'
| 'REFRESH_RECEIVED_VCS'
| 'STORE_RESPONSE'
| 'VERIFY_VC_FAILED'
| 'xstate.init';
loadReceivedVcs: 'REFRESH_RECEIVED_VCS' | 'STORE_RESPONSE';
logTamperedVCsremoved: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
prependToMyVcsMetadata: 'VC_ADDED';
removeDownloadFailedVcsFromStorage: 'DELETE_VC';
removeDownloadingFailedVcsFromMyVcs: 'STORE_RESPONSE';
removeVcFromInProgressDownlods:
| 'DOWNLOAD_LIMIT_EXPIRED'
| 'REMOVE_VC_FROM_IN_PROGRESS_DOWNLOADS'
| 'VERIFY_VC_FAILED';
removeVcFromMyVcsMetadata: 'REMOVE_VC_FROM_CONTEXT';
resetDownloadCreadentialsFailed: 'RESET_DOWNLOADING_FAILED';
resetDownloadFailedVcs: 'STORE_RESPONSE';
resetInProgressVcsDownloaded: 'RESET_IN_PROGRESS_VCS_DOWNLOADED';
resetTamperedVcs: 'REMOVE_TAMPERED_VCS';
resetVerificationErrorMessage: 'RESET_VERIFY_ERROR';
resetVerificationStatus: 'RESET_VERIFICATION_STATUS';
resetWalletBindingSuccess: 'RESET_WALLET_BINDING_SUCCESS';
sendBackupEvent: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
setDownloadCreadentialsFailed: 'VC_DOWNLOADING_FAILED';
setDownloadedVc: 'VC_DOWNLOADED';
setDownloadingFailedVcs: 'DOWNLOAD_LIMIT_EXPIRED';
setMyVcs: 'STORE_RESPONSE';
setReceivedVcs: 'STORE_RESPONSE';
setUpdatedVcMetadatas: 'VC_METADATA_UPDATED';
setVerificationErrorMessage: 'VERIFY_VC_FAILED';
setVerificationStatus: 'SET_VERIFICATION_STATUS';
setWalletBindingSuccess: 'WALLET_BINDING_SUCCESS';
updateMyVcsMetadata: 'VC_METADATA_UPDATED';
};
eventsCausingDelays: {};
eventsCausingGuards: {
isAnyVcTampered: 'SHOW_TAMPERED_POPUP';
isSignedIn: 'done.invoke.vcMeta.ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion:invocation[0]';
};
eventsCausingServices: {
isUserSignedAlready: 'REMOVE_TAMPERED_VCS';
};
matchesStates:
| 'deletingFailedVcs'
| 'ready'
| 'ready.myVcs'
| 'ready.receivedVcs'
| 'ready.showTamperedPopup'
| 'ready.tamperedVCs'
| 'ready.tamperedVCs.idle'
| 'ready.tamperedVCs.triggerAutoBackupForTamperedVcDeletion'
| {
ready?:
| 'myVcs'
| 'receivedVcs'
| 'showTamperedPopup'
| 'tamperedVCs'
| {tamperedVCs?: 'idle' | 'triggerAutoBackupForTamperedVcDeletion'};
};
tags: never;
}

View File

@@ -3,6 +3,7 @@ import {AppServices} from '../../../shared/GlobalContext';
import {VCMetadata} from '../../../shared/VCMetadata';
import {VC} from './vc';
import {VcMetaEvents} from './VCMetaEvents';
import {vcVerificationBannerDetails} from '../../../components/BannerNotificationContainer';
export const VCMetamodel = createModel(
{
@@ -17,6 +18,7 @@ export const VCMetamodel = createModel(
tamperedVcs: [] as VCMetadata[],
downloadingFailedVcs: [] as VCMetadata[], //VCDownloadFailed
verificationErrorMessage: '' as string,
verificationStatus: null as vcVerificationBannerDetails | null,
DownloadingCredentialsFailed: false,
},
{

View File

@@ -4,6 +4,10 @@ import {vcMetaMachine} from './VCMetaMachine';
type State = StateFrom<typeof vcMetaMachine>;
export function selectVerificationStatus(state: State) {
return state.context.verificationStatus;
}
export function selectMyVcsMetadata(state: State): VCMetadata[] {
return state.context.myVcsMetadata;
}

View File

@@ -1,63 +1,134 @@
// This file was automatically generated. Edits will be overwritten
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]": { type: "done.invoke.backupRestore.restoreBackup.checkInternet: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.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.checkInternet:invocation[0]": { type: "error.platform.backupRestore.restoreBackup.checkInternet:invocation[0]"; data: unknown };
"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: {
"checkInternet": "done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]";
"checkStorageAvailability": "done.invoke.backupRestore.restoreBackup.checkStorageAvailability: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: {
"cleanupFiles": "STORE_ERROR" | "STORE_RESPONSE" | "done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]" | "done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]" | "error.platform.backupRestore.restoreBackup.checkInternet:invocation[0]" | "error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]" | "error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]";
"downloadUnsyncedBackupFiles": "DOWNLOAD_UNSYNCED_BACKUP_FILES";
"loadDataToMemory": "DATA_FROM_FILE";
"refreshVCs": "STORE_RESPONSE";
"sendDataRestoreErrorEvent": "done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]" | "error.platform.backupRestore.restoreBackup.checkInternet:invocation[0]";
"sendDataRestoreFailureEvent": "STORE_ERROR" | "done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]" | "done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]" | "error.platform.backupRestore.restoreBackup.checkInternet:invocation[0]" | "error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]" | "error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]";
"sendDataRestoreStartEvent": "BACKUP_RESTORE";
"sendDataRestoreSuccessEvent": "STORE_RESPONSE";
"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]";
"setRestoreErrorReasonAsNetworkError": "done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]" | "error.platform.backupRestore.restoreBackup.checkInternet:invocation[0]";
"setRestoreTechnicalError": "STORE_ERROR" | "done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]";
"setShowRestoreInProgress": "BACKUP_RESTORE";
"unsetShowRestoreInProgress": "DISMISS_SHOW_RESTORE_IN_PROGRESS" | "STORE_ERROR" | "STORE_RESPONSE" | "done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]" | "done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]" | "error.platform.backupRestore.restoreBackup.checkInternet:invocation[0]" | "error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]" | "error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]";
};
eventsCausingDelays: {
};
eventsCausingGuards: {
"isInternetConnected": "done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]";
"isMinimumStorageRequiredForBackupRestorationReached": "done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]";
};
eventsCausingServices: {
"checkInternet": "BACKUP_RESTORE";
"checkStorageAvailability": "done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]";
"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.checkInternet" | "restoreBackup.checkStorageAvailability" | "restoreBackup.downloadBackupFileFromCloud" | "restoreBackup.failure" | "restoreBackup.loadDataToMemory" | "restoreBackup.readBackupFile" | "restoreBackup.success" | "restoreBackup.unzipBackupFile" | { "restoreBackup"?: "checkInternet" | "checkStorageAvailability" | "downloadBackupFileFromCloud" | "failure" | "loadDataToMemory" | "readBackupFile" | "success" | "unzipBackupFile"; };
tags: never;
}
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]': {
type: 'done.invoke.backupRestore.restoreBackup.checkInternet: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.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.checkInternet:invocation[0]': {
type: 'error.platform.backupRestore.restoreBackup.checkInternet:invocation[0]';
data: unknown;
};
'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: {
checkInternet: 'done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]';
checkStorageAvailability: 'done.invoke.backupRestore.restoreBackup.checkStorageAvailability: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: {
cleanupFiles:
| 'STORE_ERROR'
| 'STORE_RESPONSE'
| 'done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]'
| 'done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]'
| 'error.platform.backupRestore.restoreBackup.checkInternet:invocation[0]'
| 'error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]'
| 'error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]';
downloadUnsyncedBackupFiles: 'DOWNLOAD_UNSYNCED_BACKUP_FILES';
loadDataToMemory: 'DATA_FROM_FILE';
refreshVCs: 'STORE_RESPONSE';
sendDataRestoreErrorEvent:
| 'done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]'
| 'error.platform.backupRestore.restoreBackup.checkInternet:invocation[0]';
sendDataRestoreFailureEvent:
| 'STORE_ERROR'
| 'done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]'
| 'done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]'
| 'error.platform.backupRestore.restoreBackup.checkInternet:invocation[0]'
| 'error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]'
| 'error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]';
sendDataRestoreStartEvent: 'BACKUP_RESTORE';
sendDataRestoreSuccessEvent: 'STORE_RESPONSE';
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]';
setRestoreErrorReasonAsNetworkError:
| 'done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]'
| 'error.platform.backupRestore.restoreBackup.checkInternet:invocation[0]';
setRestoreTechnicalError:
| 'STORE_ERROR'
| 'done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]';
setShowRestoreInProgress: 'BACKUP_RESTORE';
unsetShowRestoreInProgress:
| 'DISMISS_SHOW_RESTORE_IN_PROGRESS'
| 'STORE_ERROR'
| 'STORE_RESPONSE'
| 'done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]'
| 'done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]'
| 'error.platform.backupRestore.restoreBackup.checkInternet:invocation[0]'
| 'error.platform.backupRestore.restoreBackup.downloadBackupFileFromCloud:invocation[0]'
| 'error.platform.backupRestore.restoreBackup.unzipBackupFile:invocation[0]';
};
eventsCausingDelays: {};
eventsCausingGuards: {
isInternetConnected: 'done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]';
isMinimumStorageRequiredForBackupRestorationReached: 'done.invoke.backupRestore.restoreBackup.checkStorageAvailability:invocation[0]';
};
eventsCausingServices: {
checkInternet: 'BACKUP_RESTORE';
checkStorageAvailability: 'done.invoke.backupRestore.restoreBackup.checkInternet:invocation[0]';
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.checkInternet'
| 'restoreBackup.checkStorageAvailability'
| 'restoreBackup.downloadBackupFileFromCloud'
| 'restoreBackup.failure'
| 'restoreBackup.loadDataToMemory'
| 'restoreBackup.readBackupFile'
| 'restoreBackup.success'
| 'restoreBackup.unzipBackupFile'
| {
restoreBackup?:
| 'checkInternet'
| 'checkStorageAvailability'
| 'downloadBackupFileFromCloud'
| 'failure'
| 'loadDataToMemory'
| 'readBackupFile'
| 'success'
| 'unzipBackupFile';
};
tags: never;
}

View File

@@ -1,58 +1,104 @@
// This file was automatically generated. Edits will be overwritten
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"done.invoke.WithEncryption.backingUp.checkStorageAvailability:invocation[0]": { type: "done.invoke.WithEncryption.backingUp.checkStorageAvailability:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.WithEncryption.backingUp.zipBackupFile:invocation[0]": { type: "done.invoke.WithEncryption.backingUp.zipBackupFile:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.WithEncryption.hashKey:invocation[0]": { type: "done.invoke.WithEncryption.hashKey:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"error.platform.WithEncryption.backingUp.zipBackupFile:invocation[0]": { type: "error.platform.WithEncryption.backingUp.zipBackupFile:invocation[0]"; data: unknown };
"error.platform.WithEncryption.requestOtp:invocation[0]": { type: "error.platform.WithEncryption.requestOtp:invocation[0]"; data: unknown };
"xstate.init": { type: "xstate.init" };
};
invokeSrcNameMap: {
"checkStorageAvailability": "done.invoke.WithEncryption.backingUp.checkStorageAvailability:invocation[0]";
"hashEncKey": "done.invoke.WithEncryption.hashKey:invocation[0]";
"requestOtp": "done.invoke.WithEncryption.requestOtp:invocation[0]";
"writeDataToFile": "done.invoke.WithEncryption.backingUp.writeDataToFile:invocation[0]";
"zipBackupFile": "done.invoke.WithEncryption.backingUp.zipBackupFile:invocation[0]";
};
missingImplementations: {
actions: "" | "sendDataBackupFailureEvent" | "sendDataBackupStartEvent" | "sendDataBackupSuccessEvent" | "setFileName";
delays: never;
guards: "isMinimumStorageRequiredForBackupReached";
services: "checkStorageAvailability" | "requestOtp";
};
eventsCausingActions: {
"": "error.platform.WithEncryption.requestOtp:invocation[0]";
"fetchAllDataFromDB": "done.invoke.WithEncryption.backingUp.checkStorageAvailability:invocation[0]";
"sendDataBackupFailureEvent": "done.invoke.WithEncryption.backingUp.checkStorageAvailability:invocation[0]" | "error.platform.WithEncryption.backingUp.zipBackupFile:invocation[0]";
"sendDataBackupStartEvent": "STORE_RESPONSE";
"sendDataBackupSuccessEvent": "done.invoke.WithEncryption.backingUp.zipBackupFile:invocation[0]";
"setBaseEncKey": "SET_BASE_ENC_KEY";
"setDataFromStorage": "STORE_RESPONSE";
"setFileName": "FILE_NAME";
"setHashedKey": "done.invoke.WithEncryption.hashKey:invocation[0]";
"setOtp": "INPUT_OTP";
"storeHashedEncKey": "done.invoke.WithEncryption.hashKey:invocation[0]";
"storePasswordKeyType": "SET_BASE_ENC_KEY";
"storePhoneNumberKeyType": "INPUT_OTP";
};
eventsCausingDelays: {
};
eventsCausingGuards: {
"isMinimumStorageRequiredForBackupReached": "done.invoke.WithEncryption.backingUp.checkStorageAvailability:invocation[0]";
};
eventsCausingServices: {
"checkStorageAvailability": "STORE_RESPONSE";
"hashEncKey": "INPUT_OTP" | "STORE_RESPONSE";
"requestOtp": "SEND_OTP";
"writeDataToFile": "STORE_RESPONSE";
"zipBackupFile": "FILE_NAME";
};
matchesStates: "backUp" | "backingUp" | "backingUp.checkStorageAvailability" | "backingUp.failure" | "backingUp.fetchDataFromDB" | "backingUp.idle" | "backingUp.success" | "backingUp.writeDataToFile" | "backingUp.zipBackupFile" | "hashKey" | "init" | "passwordBackup" | "phoneNumberBackup" | "requestOtp" | "selectPref" | { "backingUp"?: "checkStorageAvailability" | "failure" | "fetchDataFromDB" | "idle" | "success" | "writeDataToFile" | "zipBackupFile"; };
tags: never;
}
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'done.invoke.WithEncryption.backingUp.checkStorageAvailability:invocation[0]': {
type: 'done.invoke.WithEncryption.backingUp.checkStorageAvailability:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.WithEncryption.backingUp.zipBackupFile:invocation[0]': {
type: 'done.invoke.WithEncryption.backingUp.zipBackupFile:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.WithEncryption.hashKey:invocation[0]': {
type: 'done.invoke.WithEncryption.hashKey:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'error.platform.WithEncryption.backingUp.zipBackupFile:invocation[0]': {
type: 'error.platform.WithEncryption.backingUp.zipBackupFile:invocation[0]';
data: unknown;
};
'error.platform.WithEncryption.requestOtp:invocation[0]': {
type: 'error.platform.WithEncryption.requestOtp:invocation[0]';
data: unknown;
};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
checkStorageAvailability: 'done.invoke.WithEncryption.backingUp.checkStorageAvailability:invocation[0]';
hashEncKey: 'done.invoke.WithEncryption.hashKey:invocation[0]';
requestOtp: 'done.invoke.WithEncryption.requestOtp:invocation[0]';
writeDataToFile: 'done.invoke.WithEncryption.backingUp.writeDataToFile:invocation[0]';
zipBackupFile: 'done.invoke.WithEncryption.backingUp.zipBackupFile:invocation[0]';
};
missingImplementations: {
actions:
| ''
| 'sendDataBackupFailureEvent'
| 'sendDataBackupStartEvent'
| 'sendDataBackupSuccessEvent'
| 'setFileName';
delays: never;
guards: 'isMinimumStorageRequiredForBackupReached';
services: 'checkStorageAvailability' | 'requestOtp';
};
eventsCausingActions: {
'': 'error.platform.WithEncryption.requestOtp:invocation[0]';
fetchAllDataFromDB: 'done.invoke.WithEncryption.backingUp.checkStorageAvailability:invocation[0]';
sendDataBackupFailureEvent:
| 'done.invoke.WithEncryption.backingUp.checkStorageAvailability:invocation[0]'
| 'error.platform.WithEncryption.backingUp.zipBackupFile:invocation[0]';
sendDataBackupStartEvent: 'STORE_RESPONSE';
sendDataBackupSuccessEvent: 'done.invoke.WithEncryption.backingUp.zipBackupFile:invocation[0]';
setBaseEncKey: 'SET_BASE_ENC_KEY';
setDataFromStorage: 'STORE_RESPONSE';
setFileName: 'FILE_NAME';
setHashedKey: 'done.invoke.WithEncryption.hashKey:invocation[0]';
setOtp: 'INPUT_OTP';
storeHashedEncKey: 'done.invoke.WithEncryption.hashKey:invocation[0]';
storePasswordKeyType: 'SET_BASE_ENC_KEY';
storePhoneNumberKeyType: 'INPUT_OTP';
};
eventsCausingDelays: {};
eventsCausingGuards: {
isMinimumStorageRequiredForBackupReached: 'done.invoke.WithEncryption.backingUp.checkStorageAvailability:invocation[0]';
};
eventsCausingServices: {
checkStorageAvailability: 'STORE_RESPONSE';
hashEncKey: 'INPUT_OTP' | 'STORE_RESPONSE';
requestOtp: 'SEND_OTP';
writeDataToFile: 'STORE_RESPONSE';
zipBackupFile: 'FILE_NAME';
};
matchesStates:
| 'backUp'
| 'backingUp'
| 'backingUp.checkStorageAvailability'
| 'backingUp.failure'
| 'backingUp.fetchDataFromDB'
| 'backingUp.idle'
| 'backingUp.success'
| 'backingUp.writeDataToFile'
| 'backingUp.zipBackupFile'
| 'hashKey'
| 'init'
| 'passwordBackup'
| 'phoneNumberBackup'
| 'requestOtp'
| 'selectPref'
| {
backingUp?:
| 'checkStorageAvailability'
| 'failure'
| 'fetchDataFromDB'
| 'idle'
| 'success'
| 'writeDataToFile'
| 'zipBackupFile';
};
tags: never;
}

View File

@@ -1,25 +1,40 @@
import { Linking } from "react-native";
import { getDeviceNameSync } from "react-native-device-info";
import { assign, spawn, send, DoneInvokeEvent } from "xstate";
import { VCShareFlowType } from "../../../shared/Utils";
import { VCMetadata } from "../../../shared/VCMetadata";
import { logState } from "../../../shared/commonUtil";
import { SHOW_FACE_AUTH_CONSENT_SHARE_FLOW, isAndroid, DEFAULT_QR_HEADER, MY_VCS_STORE_KEY, MY_LOGIN_STORE_KEY } from "../../../shared/constants";
import { getIdType } from "../../../shared/openId4VCI/Utils";
import { TelemetryConstants } from "../../../shared/telemetry/TelemetryConstants";
import { sendImpressionEvent, getImpressionEventData, sendEndEvent, getEndEventData, sendErrorEvent, getErrorEventData, sendStartEvent, getStartEventData } from "../../../shared/telemetry/TelemetryUtils";
import { createQrLoginMachine } from "../../QrLogin/QrLoginMachine";
import { VcMetaEvents } from "../../VerifiableCredential/VCMetaMachine/VCMetaEvents";
import { ActivityLogEvents } from "../../activityLog";
import { StoreEvents } from "../../store";
import {Linking} from 'react-native';
import {getDeviceNameSync} from 'react-native-device-info';
import {assign, spawn, send, DoneInvokeEvent} from 'xstate';
import {VCShareFlowType} from '../../../shared/Utils';
import {VCMetadata} from '../../../shared/VCMetadata';
import {logState} from '../../../shared/commonUtil';
import {
SHOW_FACE_AUTH_CONSENT_SHARE_FLOW,
isAndroid,
DEFAULT_QR_HEADER,
MY_VCS_STORE_KEY,
MY_LOGIN_STORE_KEY,
} from '../../../shared/constants';
import {getIdType} from '../../../shared/openId4VCI/Utils';
import {TelemetryConstants} from '../../../shared/telemetry/TelemetryConstants';
import {
sendImpressionEvent,
getImpressionEventData,
sendEndEvent,
getEndEventData,
sendErrorEvent,
getErrorEventData,
sendStartEvent,
getStartEventData,
} from '../../../shared/telemetry/TelemetryUtils';
import {createQrLoginMachine} from '../../QrLogin/QrLoginMachine';
import {VcMetaEvents} from '../../VerifiableCredential/VCMetaMachine/VCMetaEvents';
import {ActivityLogEvents} from '../../activityLog';
import {StoreEvents} from '../../store';
import tuvali from '@mosip/tuvali';
import BluetoothStateManager from 'react-native-bluetooth-state-manager';
const {wallet, EventTypes, VerificationStatus} = tuvali;
export const ScanActions =(model:any,QR_LOGIN_REF_ID:any)=>{
return{
export const ScanActions = (model: any, QR_LOGIN_REF_ID: any) => {
return {
setChildRef: assign({
QrLoginRef: (context:any) => {
QrLoginRef: (context: any) => {
const service = spawn(
createQrLoginMachine(context.serviceRefs),
QR_LOGIN_REF_ID,
@@ -35,22 +50,27 @@ export const ScanActions =(model:any,QR_LOGIN_REF_ID:any)=>{
},
}),
setShowFaceAuthConsent: model.assign({
showFaceAuthConsent: (_, event) => {
return !event.isDoNotAskAgainChecked;
},
}),
getFaceAuthConsent: send(StoreEvents.GET(SHOW_FACE_AUTH_CONSENT_SHARE_FLOW), {
to: (context:any) => context.serviceRefs.store,
}),
getFaceAuthConsent: send(
StoreEvents.GET(SHOW_FACE_AUTH_CONSENT_SHARE_FLOW),
{
to: (context: any) => context.serviceRefs.store,
},
),
storeShowFaceAuthConsent: send(
(context, event) =>
StoreEvents.SET(SHOW_FACE_AUTH_CONSENT_SHARE_FLOW, !event.isDoNotAskAgainChecked),
StoreEvents.SET(
SHOW_FACE_AUTH_CONSENT_SHARE_FLOW,
!event.isDoNotAskAgainChecked,
),
{
to: (context:any) => context.serviceRefs.store,
to: (context: any) => context.serviceRefs.store,
},
),
@@ -168,7 +188,7 @@ export const ScanActions =(model:any,QR_LOGIN_REF_ID:any)=>{
}),
logShared: send(
(context:any) => {
(context: any) => {
const vcMetadata = context.selectedVc?.vcMetadata;
return ActivityLogEvents.LOG_ACTIVITY({
_vcKey: VCMetadata.fromVC(vcMetadata).getVcKey(),
@@ -210,14 +230,14 @@ export const ScanActions =(model:any,QR_LOGIN_REF_ID:any)=>{
JSON.parse(decodeData(event.params.split(DEFAULT_QR_HEADER)[1])),
}),
loadMetaDataToMemory: send(
(context:any) => {
(context: any) => {
let metadata = VCMetadata.fromVC(context.quickShareData?.meta);
return StoreEvents.PREPEND(MY_VCS_STORE_KEY, metadata);
},
{to: context => context.serviceRefs.store},
),
loadVCDataToMemory: send(
(context:any) => {
(context: any) => {
let metadata = VCMetadata.fromVC(context.quickShareData?.meta);
let verifiableCredential = metadata.isFromOpenId4VCI()
@@ -240,7 +260,7 @@ export const ScanActions =(model:any,QR_LOGIN_REF_ID:any)=>{
(event as DoneInvokeEvent<string>).data,
);
},
{to: (context:any) => context.serviceRefs.store},
{to: (context: any) => context.serviceRefs.store},
),
storingActivityLog: send(
@@ -255,7 +275,7 @@ export const ScanActions =(model:any,QR_LOGIN_REF_ID:any)=>{
vcLabel: String(event.response.selectedVc.vcMetadata.id),
}),
{
to: (context:any) => context.serviceRefs.activityLog,
to: (context: any) => context.serviceRefs.activityLog,
},
),
@@ -321,7 +341,5 @@ export const ScanActions =(model:any,QR_LOGIN_REF_ID:any)=>{
),
);
},
}
}
};
};

View File

@@ -1,45 +1,43 @@
import { VCShareFlowType } from "../../../shared/Utils";
import { androidVersion, isAndroid, isIOS } from "../../../shared/constants";
import {VCShareFlowType} from '../../../shared/Utils';
import {androidVersion, isAndroid, isIOS} from '../../../shared/constants';
export const ScanGuards = () => {
return {
showFaceAuthConsentScreen: context => {
return context.showFaceAuthConsent;
},
// sample: 'OPENID4VP://connect:?name=OVPMOSIP&key=69dc92a2cc91f02258aa8094d6e2b62877f5b6498924fbaedaaa46af30abb364'
isOpenIdQr: (_context, event) =>
event.params.startsWith('OPENID4VP://'),
// sample: 'INJIQUICKSHARE://NAKDFK:DB:JAHDIHAIDJXKABDAJDHUHW'
isQuickShare: (_context, event) =>
// event.params.startsWith(DEFAULT_QR_HEADER),
// toggling the feature for now
false,
isQrLogin: (context, event) => {
try {
let linkCode = new URL(event.params);
// sample: 'inji://landing-page-name?linkCode=sTjp0XVH3t3dGCU&linkExpireDateTime=2023-11-09T06:56:18.482Z'
return linkCode.searchParams.get('linkCode') !== null;
} catch (e) {
return false;
}
},
uptoAndroid11: () => isAndroid() && androidVersion < 31,
isIOS: () => isIOS(),
isMinimumStorageRequiredForAuditEntryReached: (_context, event) =>
Boolean(event.data),
isFlowTypeMiniViewShareWithSelfie: context =>
context.flowType === VCShareFlowType.MINI_VIEW_SHARE_WITH_SELFIE,
isFlowTypeMiniViewShare: context =>
context.flowType === VCShareFlowType.MINI_VIEW_SHARE,
isFlowTypeSimpleShare: context =>
context.flowType === VCShareFlowType.SIMPLE_SHARE,
};
return {
showFaceAuthConsentScreen: context => {
return context.showFaceAuthConsent;
},
// sample: 'OPENID4VP://connect:?name=OVPMOSIP&key=69dc92a2cc91f02258aa8094d6e2b62877f5b6498924fbaedaaa46af30abb364'
isOpenIdQr: (_context, event) => event.params.startsWith('OPENID4VP://'),
// sample: 'INJIQUICKSHARE://NAKDFK:DB:JAHDIHAIDJXKABDAJDHUHW'
isQuickShare: (_context, event) =>
// event.params.startsWith(DEFAULT_QR_HEADER),
// toggling the feature for now
false,
isQrLogin: (context, event) => {
try {
let linkCode = new URL(event.params);
// sample: 'inji://landing-page-name?linkCode=sTjp0XVH3t3dGCU&linkExpireDateTime=2023-11-09T06:56:18.482Z'
return linkCode.searchParams.get('linkCode') !== null;
} catch (e) {
return false;
}
},
uptoAndroid11: () => isAndroid() && androidVersion < 31,
isIOS: () => isIOS(),
isMinimumStorageRequiredForAuditEntryReached: (_context, event) =>
Boolean(event.data),
isFlowTypeMiniViewShareWithSelfie: context =>
context.flowType === VCShareFlowType.MINI_VIEW_SHARE_WITH_SELFIE,
isFlowTypeMiniViewShare: context =>
context.flowType === VCShareFlowType.MINI_VIEW_SHARE,
isFlowTypeSimpleShare: context =>
context.flowType === VCShareFlowType.SIMPLE_SHARE,
};
};

View File

@@ -1,23 +1,19 @@
/* eslint-disable sonarjs/no-duplicate-string */
import {
EventFrom,
send,
StateFrom
} from 'xstate';
import { AppServices } from '../../../shared/GlobalContext';
import { TelemetryConstants } from '../../../shared/telemetry/TelemetryConstants';
import {EventFrom, send, StateFrom} from 'xstate';
import {AppServices} from '../../../shared/GlobalContext';
import {TelemetryConstants} from '../../../shared/telemetry/TelemetryConstants';
import {
getStartEventData,
sendStartEvent
sendStartEvent,
} from '../../../shared/telemetry/TelemetryUtils';
import { qrLoginMachine } from '../../QrLogin/QrLoginMachine';
import {qrLoginMachine} from '../../QrLogin/QrLoginMachine';
// @ts-ignore
import { ScanActions } from './scanActions';
import { ScanGuards } from './scanGuards';
import { ScanModel } from './scanModel';
import { ScanServices } from './scanServices';
import {ScanActions} from './scanActions';
import {ScanGuards} from './scanGuards';
import {ScanModel} from './scanModel';
import {ScanServices} from './scanServices';
const model=ScanModel;
const model = ScanModel;
const QR_LOGIN_REF_ID = 'QrLogin';
export const ScanEvents = model.events;
@@ -49,7 +45,7 @@ export const scanMachine =
actions: ['sendBLEConnectionErrorEvent', 'setBleError'],
},
RESET: {
actions:['removeLoggers', 'resetFlowType', 'resetSelectedVc'],
actions: ['removeLoggers', 'resetFlowType', 'resetSelectedVc'],
target: '.checkStorage',
},
DISMISS: {
@@ -87,7 +83,7 @@ export const scanMachine =
target: 'restrictSharingVc',
},
{
target: 'startPermissionCheck',
target: 'startPermissionCheck',
},
],
},
@@ -445,7 +441,7 @@ export const scanMachine =
},
{
cond: 'isFlowTypeMiniViewShareWithSelfie',
target:'.checkFaceAuthConsentForMiniView' ,
target: '.checkFaceAuthConsentForMiniView',
},
],
},
@@ -585,15 +581,16 @@ export const scanMachine =
always: '#scan.disconnected',
},
checkFaceAuthConsentForMiniView: {
always:[
{
cond: 'showFaceAuthConsentScreen',
target: 'faceVerificationConsent'
},
{
target: 'verifyingIdentity'
}
],},
always: [
{
cond: 'showFaceAuthConsentScreen',
target: 'faceVerificationConsent',
},
{
target: 'verifyingIdentity',
},
],
},
faceVerificationConsent: {
on: {
FACE_VERIFICATION_CONSENT: {
@@ -603,14 +600,14 @@ export const scanMachine =
],
target: 'verifyingIdentity',
},
DISMISS:[
DISMISS: [
{
cond: 'isFlowTypeMiniViewShareWithSelfie',
target: '#scan.checkFaceAuthConsent',
target: '#scan.checkFaceAuthConsent',
},
{
target: '#scan.reviewing.selectingVc',
}
},
],
},
},
@@ -759,7 +756,7 @@ export const scanMachine =
},
},
{
actions: ScanActions(model,QR_LOGIN_REF_ID),
actions: ScanActions(model, QR_LOGIN_REF_ID),
services: ScanServices(model),
@@ -770,8 +767,6 @@ export const scanMachine =
SHARING_TIMEOUT: 15 * 1000,
},
},
);
type State = StateFrom<typeof scanMachine>;
@@ -782,4 +777,3 @@ export function createScanMachine(serviceRefs: AppServices) {
serviceRefs,
});
}

View File

@@ -1,121 +1,310 @@
// This file was automatically generated. Edits will be overwritten
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"": { type: "" };
"done.invoke.QrLogin": { type: "done.invoke.QrLogin"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.scan.checkStorage:invocation[0]": { type: "done.invoke.scan.checkStorage:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection": { type: "xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection" };
"xstate.init": { type: "xstate.init" };
};
invokeSrcNameMap: {
"checkBluetoothPermission": "done.invoke.scan.checkBluetoothPermission.checking:invocation[0]";
"checkBluetoothState": "done.invoke.scan.checkBluetoothState.checking:invocation[0]" | "done.invoke.scan.recheckBluetoothState.checking:invocation[0]";
"checkLocationPermission": "done.invoke.scan.checkingLocationState.checkingPermissionStatus:invocation[0]";
"checkLocationStatus": "done.invoke.scan.checkingLocationState.checkLocationService:invocation[0]";
"checkNearByDevicesPermission": "done.invoke.scan.checkNearbyDevicesPermission.checking:invocation[0]";
"checkStorageAvailability": "done.invoke.scan.checkStorage:invocation[0]";
"disconnect": "done.invoke.scan.clearingConnection:invocation[0]" | "done.invoke.scan.disconnectDevice:invocation[0]" | "done.invoke.scan.reviewing.disconnect:invocation[0]";
"monitorConnection": "done.invoke.scan:invocation[0]";
"requestBluetooth": "done.invoke.scan.checkBluetoothState.requesting:invocation[0]";
"requestNearByDevicesPermission": "done.invoke.scan.checkNearbyDevicesPermission.requesting:invocation[0]";
"requestToEnableLocationPermission": "done.invoke.scan.checkingLocationState.requestToEnableLocation:invocation[0]";
"sendVc": "done.invoke.scan.reviewing.sendingVc:invocation[0]";
"startConnection": "done.invoke.scan.connecting:invocation[0]";
};
missingImplementations: {
actions: "clearUri" | "enableLocation" | "getFaceAuthConsent" | "loadMetaDataToMemory" | "loadVCDataToMemory" | "logFailedVerification" | "logShared" | "openAppPermission" | "openBluetoothSettings" | "refreshVCs" | "registerLoggers" | "removeLoggers" | "resetFaceCaptureBannerStatus" | "resetFlowType" | "resetSelectedVc" | "resetShowQuickShareSuccessBanner" | "sendBLEConnectionErrorEvent" | "sendScanData" | "sendVCShareFlowCancelEndEvent" | "sendVCShareFlowTimeoutEndEvent" | "sendVcShareSuccessEvent" | "sendVcSharingStartEvent" | "setBleError" | "setChildRef" | "setFlowType" | "setLinkCode" | "setQuickShareData" | "setReadyForBluetoothStateCheck" | "setReceiverInfo" | "setSelectedVc" | "setSenderInfo" | "setShareLogTypeUnverified" | "setShareLogTypeVerified" | "setShowFaceAuthConsent" | "setShowQuickShareSuccessBanner" | "setUri" | "storeLoginItem" | "storeShowFaceAuthConsent" | "storingActivityLog" | "updateFaceCaptureBannerStatus" | "updateShowFaceAuthConsent";
delays: never;
guards: "isFlowTypeMiniViewShare" | "isFlowTypeMiniViewShareWithSelfie" | "isFlowTypeSimpleShare" | "isIOS" | "isMinimumStorageRequiredForAuditEntryReached" | "isOpenIdQr" | "isQrLogin" | "isQuickShare" | "showFaceAuthConsentScreen" | "uptoAndroid11";
services: "checkBluetoothPermission" | "checkBluetoothState" | "checkLocationPermission" | "checkLocationStatus" | "checkNearByDevicesPermission" | "checkStorageAvailability" | "disconnect" | "monitorConnection" | "requestBluetooth" | "requestNearByDevicesPermission" | "requestToEnableLocationPermission" | "sendVc" | "startConnection";
};
eventsCausingActions: {
"clearUri": "STORE_RESPONSE";
"enableLocation": "ALLOWED" | "LOCATION_REQUEST";
"getFaceAuthConsent": "DISCONNECT" | "DISMISS" | "xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection";
"loadMetaDataToMemory": "SCAN";
"loadVCDataToMemory": "STORE_RESPONSE";
"logFailedVerification": "FACE_INVALID";
"logShared": "VC_ACCEPTED";
"openAppPermission": "GOTO_SETTINGS" | "LOCATION_REQUEST";
"openBluetoothSettings": "GOTO_SETTINGS";
"refreshVCs": "STORE_RESPONSE";
"registerLoggers": "STORE_RESPONSE";
"removeLoggers": "DISCONNECT" | "DISMISS" | "DISMISS_QUICK_SHARE_BANNER" | "RESET" | "SCREEN_BLUR" | "STORE_RESPONSE" | "xstate.init";
"resetFaceCaptureBannerStatus": "ACCEPT_REQUEST" | "CLOSE_BANNER";
"resetFlowType": "DISCONNECT" | "DISMISS" | "DISMISS_QUICK_SHARE_BANNER" | "GOTO_HISTORY" | "RESET" | "SCREEN_BLUR" | "xstate.init";
"resetSelectedVc": "DISCONNECT" | "DISMISS" | "DISMISS_QUICK_SHARE_BANNER" | "GOTO_HISTORY" | "RESET" | "SCREEN_BLUR" | "xstate.init";
"resetShowQuickShareSuccessBanner": "DISMISS" | "DISMISS_QUICK_SHARE_BANNER";
"sendBLEConnectionErrorEvent": "BLE_ERROR";
"sendScanData": "SCAN";
"sendVCShareFlowCancelEndEvent": "CANCEL";
"sendVCShareFlowTimeoutEndEvent": "CANCEL" | "RETRY";
"sendVcShareSuccessEvent": "VC_ACCEPTED";
"sendVcSharingStartEvent": "SCAN";
"setBleError": "BLE_ERROR";
"setChildRef": "STORE_RESPONSE";
"setFlowType": "SELECT_VC";
"setLinkCode": "SCAN";
"setQuickShareData": "SCAN";
"setReadyForBluetoothStateCheck": "BLUETOOTH_PERMISSION_ENABLED";
"setReceiverInfo": "CONNECTED";
"setSelectedVc": "SELECT_VC";
"setSenderInfo": "CONNECTED";
"setShareLogTypeUnverified": "ACCEPT_REQUEST" | "CHECK_FLOW_TYPE";
"setShareLogTypeVerified": "FACE_VALID";
"setShowFaceAuthConsent": "FACE_VERIFICATION_CONSENT";
"setShowQuickShareSuccessBanner": "STORE_RESPONSE";
"setUri": "SCAN";
"storeLoginItem": "done.invoke.QrLogin";
"storeShowFaceAuthConsent": "FACE_VERIFICATION_CONSENT";
"storingActivityLog": "STORE_RESPONSE";
"updateFaceCaptureBannerStatus": "FACE_VALID";
"updateShowFaceAuthConsent": "STORE_RESPONSE";
};
eventsCausingDelays: {
"CONNECTION_TIMEOUT": "SCAN";
"DESTROY_TIMEOUT": "" | "DISMISS" | "LOCATION_ENABLED" | "RETRY";
"SHARING_TIMEOUT": "ACCEPT_REQUEST" | "CHECK_FLOW_TYPE" | "FACE_VALID";
};
eventsCausingGuards: {
"isFlowTypeMiniViewShare": "CHECK_FLOW_TYPE";
"isFlowTypeMiniViewShareWithSelfie": "CHECK_FLOW_TYPE" | "DISMISS";
"isFlowTypeSimpleShare": "CANCEL" | "CHECK_FLOW_TYPE" | "DISMISS";
"isIOS": "BLUETOOTH_STATE_DISABLED" | "START_PERMISSION_CHECK";
"isMinimumStorageRequiredForAuditEntryReached": "done.invoke.scan.checkStorage:invocation[0]";
"isOpenIdQr": "SCAN";
"isQrLogin": "SCAN";
"isQuickShare": "SCAN";
"showFaceAuthConsentScreen": "" | "VERIFY_AND_ACCEPT_REQUEST";
"uptoAndroid11": "" | "START_PERMISSION_CHECK";
};
eventsCausingServices: {
"QrLogin": "SCAN";
"checkBluetoothPermission": "" | "BLUETOOTH_STATE_DISABLED" | "NEARBY_ENABLED" | "START_PERMISSION_CHECK";
"checkBluetoothState": "" | "APP_ACTIVE";
"checkLocationPermission": "LOCATION_ENABLED";
"checkLocationStatus": "" | "APP_ACTIVE" | "LOCATION_REQUEST";
"checkNearByDevicesPermission": "APP_ACTIVE" | "START_PERMISSION_CHECK";
"checkStorageAvailability": "RESET" | "SCREEN_FOCUS" | "SELECT_VC";
"disconnect": "" | "DISMISS" | "LOCATION_ENABLED" | "RETRY" | "SCREEN_BLUR";
"monitorConnection": "DISMISS" | "SCREEN_BLUR" | "xstate.init";
"requestBluetooth": "BLUETOOTH_STATE_DISABLED";
"requestNearByDevicesPermission": "NEARBY_DISABLED";
"requestToEnableLocationPermission": "LOCATION_DISABLED";
"sendVc": "ACCEPT_REQUEST" | "CHECK_FLOW_TYPE" | "FACE_VALID";
"startConnection": "SCAN";
};
matchesStates: "bluetoothDenied" | "bluetoothPermissionDenied" | "checkBluetoothPermission" | "checkBluetoothPermission.checking" | "checkBluetoothPermission.enabled" | "checkBluetoothState" | "checkBluetoothState.checking" | "checkBluetoothState.enabled" | "checkBluetoothState.requesting" | "checkFaceAuthConsent" | "checkNearbyDevicesPermission" | "checkNearbyDevicesPermission.checking" | "checkNearbyDevicesPermission.enabled" | "checkNearbyDevicesPermission.requesting" | "checkStorage" | "checkingLocationState" | "checkingLocationState.LocationPermissionRationale" | "checkingLocationState.checkLocationService" | "checkingLocationState.checkingPermissionStatus" | "checkingLocationState.denied" | "checkingLocationState.disabled" | "checkingLocationState.requestToEnableLocation" | "clearingConnection" | "connecting" | "connecting.inProgress" | "connecting.timeout" | "decodeQuickShareData" | "disconnectDevice" | "disconnected" | "findingConnection" | "handlingBleError" | "inactive" | "invalid" | "loadVCS" | "loadVCS.idle" | "loadVCS.navigatingToHome" | "nearByDevicesPermissionDenied" | "recheckBluetoothState" | "recheckBluetoothState.checking" | "recheckBluetoothState.enabled" | "restrictSharingVc" | "reviewing" | "reviewing.accepted" | "reviewing.cancelling" | "reviewing.checkFaceAuthConsentForMiniView" | "reviewing.disconnect" | "reviewing.faceVerificationConsent" | "reviewing.idle" | "reviewing.invalidIdentity" | "reviewing.navigateToHistory" | "reviewing.rejected" | "reviewing.selectingVc" | "reviewing.sendingVc" | "reviewing.sendingVc.inProgress" | "reviewing.sendingVc.sent" | "reviewing.sendingVc.timeout" | "reviewing.verifyingIdentity" | "showQrLogin" | "showQrLogin.idle" | "showQrLogin.navigatingToHistory" | "showQrLogin.storing" | "startPermissionCheck" | { "checkBluetoothPermission"?: "checking" | "enabled";
"checkBluetoothState"?: "checking" | "enabled" | "requesting";
"checkNearbyDevicesPermission"?: "checking" | "enabled" | "requesting";
"checkingLocationState"?: "LocationPermissionRationale" | "checkLocationService" | "checkingPermissionStatus" | "denied" | "disabled" | "requestToEnableLocation";
"connecting"?: "inProgress" | "timeout";
"loadVCS"?: "idle" | "navigatingToHome";
"recheckBluetoothState"?: "checking" | "enabled";
"reviewing"?: "accepted" | "cancelling" | "checkFaceAuthConsentForMiniView" | "disconnect" | "faceVerificationConsent" | "idle" | "invalidIdentity" | "navigateToHistory" | "rejected" | "selectingVc" | "sendingVc" | "verifyingIdentity" | { "sendingVc"?: "inProgress" | "sent" | "timeout"; };
"showQrLogin"?: "idle" | "navigatingToHistory" | "storing"; };
tags: never;
}
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'': {type: ''};
'done.invoke.QrLogin': {
type: 'done.invoke.QrLogin';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.scan.checkStorage:invocation[0]': {
type: 'done.invoke.scan.checkStorage:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection': {
type: 'xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection';
};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
checkBluetoothPermission: 'done.invoke.scan.checkBluetoothPermission.checking:invocation[0]';
checkBluetoothState:
| 'done.invoke.scan.checkBluetoothState.checking:invocation[0]'
| 'done.invoke.scan.recheckBluetoothState.checking:invocation[0]';
checkLocationPermission: 'done.invoke.scan.checkingLocationState.checkingPermissionStatus:invocation[0]';
checkLocationStatus: 'done.invoke.scan.checkingLocationState.checkLocationService:invocation[0]';
checkNearByDevicesPermission: 'done.invoke.scan.checkNearbyDevicesPermission.checking:invocation[0]';
checkStorageAvailability: 'done.invoke.scan.checkStorage:invocation[0]';
disconnect:
| 'done.invoke.scan.clearingConnection:invocation[0]'
| 'done.invoke.scan.disconnectDevice:invocation[0]'
| 'done.invoke.scan.reviewing.disconnect:invocation[0]';
monitorConnection: 'done.invoke.scan:invocation[0]';
requestBluetooth: 'done.invoke.scan.checkBluetoothState.requesting:invocation[0]';
requestNearByDevicesPermission: 'done.invoke.scan.checkNearbyDevicesPermission.requesting:invocation[0]';
requestToEnableLocationPermission: 'done.invoke.scan.checkingLocationState.requestToEnableLocation:invocation[0]';
sendVc: 'done.invoke.scan.reviewing.sendingVc:invocation[0]';
startConnection: 'done.invoke.scan.connecting:invocation[0]';
};
missingImplementations: {
actions:
| 'clearUri'
| 'enableLocation'
| 'getFaceAuthConsent'
| 'loadMetaDataToMemory'
| 'loadVCDataToMemory'
| 'logFailedVerification'
| 'logShared'
| 'openAppPermission'
| 'openBluetoothSettings'
| 'refreshVCs'
| 'registerLoggers'
| 'removeLoggers'
| 'resetFaceCaptureBannerStatus'
| 'resetFlowType'
| 'resetSelectedVc'
| 'resetShowQuickShareSuccessBanner'
| 'sendBLEConnectionErrorEvent'
| 'sendScanData'
| 'sendVCShareFlowCancelEndEvent'
| 'sendVCShareFlowTimeoutEndEvent'
| 'sendVcShareSuccessEvent'
| 'sendVcSharingStartEvent'
| 'setBleError'
| 'setChildRef'
| 'setFlowType'
| 'setLinkCode'
| 'setQuickShareData'
| 'setReadyForBluetoothStateCheck'
| 'setReceiverInfo'
| 'setSelectedVc'
| 'setSenderInfo'
| 'setShareLogTypeUnverified'
| 'setShareLogTypeVerified'
| 'setShowFaceAuthConsent'
| 'setShowQuickShareSuccessBanner'
| 'setUri'
| 'storeLoginItem'
| 'storeShowFaceAuthConsent'
| 'storingActivityLog'
| 'updateFaceCaptureBannerStatus'
| 'updateShowFaceAuthConsent';
delays: never;
guards:
| 'isFlowTypeMiniViewShare'
| 'isFlowTypeMiniViewShareWithSelfie'
| 'isFlowTypeSimpleShare'
| 'isIOS'
| 'isMinimumStorageRequiredForAuditEntryReached'
| 'isOpenIdQr'
| 'isQrLogin'
| 'isQuickShare'
| 'showFaceAuthConsentScreen'
| 'uptoAndroid11';
services:
| 'checkBluetoothPermission'
| 'checkBluetoothState'
| 'checkLocationPermission'
| 'checkLocationStatus'
| 'checkNearByDevicesPermission'
| 'checkStorageAvailability'
| 'disconnect'
| 'monitorConnection'
| 'requestBluetooth'
| 'requestNearByDevicesPermission'
| 'requestToEnableLocationPermission'
| 'sendVc'
| 'startConnection';
};
eventsCausingActions: {
clearUri: 'STORE_RESPONSE';
enableLocation: 'ALLOWED' | 'LOCATION_REQUEST';
getFaceAuthConsent:
| 'DISCONNECT'
| 'DISMISS'
| 'xstate.after(DESTROY_TIMEOUT)#scan.clearingConnection';
loadMetaDataToMemory: 'SCAN';
loadVCDataToMemory: 'STORE_RESPONSE';
logFailedVerification: 'FACE_INVALID';
logShared: 'VC_ACCEPTED';
openAppPermission: 'GOTO_SETTINGS' | 'LOCATION_REQUEST';
openBluetoothSettings: 'GOTO_SETTINGS';
refreshVCs: 'STORE_RESPONSE';
registerLoggers: 'STORE_RESPONSE';
removeLoggers:
| 'DISCONNECT'
| 'DISMISS'
| 'DISMISS_QUICK_SHARE_BANNER'
| 'RESET'
| 'SCREEN_BLUR'
| 'STORE_RESPONSE'
| 'xstate.init';
resetFaceCaptureBannerStatus: 'ACCEPT_REQUEST' | 'CLOSE_BANNER';
resetFlowType:
| 'DISCONNECT'
| 'DISMISS'
| 'DISMISS_QUICK_SHARE_BANNER'
| 'GOTO_HISTORY'
| 'RESET'
| 'SCREEN_BLUR'
| 'xstate.init';
resetSelectedVc:
| 'DISCONNECT'
| 'DISMISS'
| 'DISMISS_QUICK_SHARE_BANNER'
| 'GOTO_HISTORY'
| 'RESET'
| 'SCREEN_BLUR'
| 'xstate.init';
resetShowQuickShareSuccessBanner: 'DISMISS' | 'DISMISS_QUICK_SHARE_BANNER';
sendBLEConnectionErrorEvent: 'BLE_ERROR';
sendScanData: 'SCAN';
sendVCShareFlowCancelEndEvent: 'CANCEL';
sendVCShareFlowTimeoutEndEvent: 'CANCEL' | 'RETRY';
sendVcShareSuccessEvent: 'VC_ACCEPTED';
sendVcSharingStartEvent: 'SCAN';
setBleError: 'BLE_ERROR';
setChildRef: 'STORE_RESPONSE';
setFlowType: 'SELECT_VC';
setLinkCode: 'SCAN';
setQuickShareData: 'SCAN';
setReadyForBluetoothStateCheck: 'BLUETOOTH_PERMISSION_ENABLED';
setReceiverInfo: 'CONNECTED';
setSelectedVc: 'SELECT_VC';
setSenderInfo: 'CONNECTED';
setShareLogTypeUnverified: 'ACCEPT_REQUEST' | 'CHECK_FLOW_TYPE';
setShareLogTypeVerified: 'FACE_VALID';
setShowFaceAuthConsent: 'FACE_VERIFICATION_CONSENT';
setShowQuickShareSuccessBanner: 'STORE_RESPONSE';
setUri: 'SCAN';
storeLoginItem: 'done.invoke.QrLogin';
storeShowFaceAuthConsent: 'FACE_VERIFICATION_CONSENT';
storingActivityLog: 'STORE_RESPONSE';
updateFaceCaptureBannerStatus: 'FACE_VALID';
updateShowFaceAuthConsent: 'STORE_RESPONSE';
};
eventsCausingDelays: {
CONNECTION_TIMEOUT: 'SCAN';
DESTROY_TIMEOUT: '' | 'DISMISS' | 'LOCATION_ENABLED' | 'RETRY';
SHARING_TIMEOUT: 'ACCEPT_REQUEST' | 'CHECK_FLOW_TYPE' | 'FACE_VALID';
};
eventsCausingGuards: {
isFlowTypeMiniViewShare: 'CHECK_FLOW_TYPE';
isFlowTypeMiniViewShareWithSelfie: 'CHECK_FLOW_TYPE' | 'DISMISS';
isFlowTypeSimpleShare: 'CANCEL' | 'CHECK_FLOW_TYPE' | 'DISMISS';
isIOS: 'BLUETOOTH_STATE_DISABLED' | 'START_PERMISSION_CHECK';
isMinimumStorageRequiredForAuditEntryReached: 'done.invoke.scan.checkStorage:invocation[0]';
isOpenIdQr: 'SCAN';
isQrLogin: 'SCAN';
isQuickShare: 'SCAN';
showFaceAuthConsentScreen: '' | 'VERIFY_AND_ACCEPT_REQUEST';
uptoAndroid11: '' | 'START_PERMISSION_CHECK';
};
eventsCausingServices: {
QrLogin: 'SCAN';
checkBluetoothPermission:
| ''
| 'BLUETOOTH_STATE_DISABLED'
| 'NEARBY_ENABLED'
| 'START_PERMISSION_CHECK';
checkBluetoothState: '' | 'APP_ACTIVE';
checkLocationPermission: 'LOCATION_ENABLED';
checkLocationStatus: '' | 'APP_ACTIVE' | 'LOCATION_REQUEST';
checkNearByDevicesPermission: 'APP_ACTIVE' | 'START_PERMISSION_CHECK';
checkStorageAvailability: 'RESET' | 'SCREEN_FOCUS' | 'SELECT_VC';
disconnect: '' | 'DISMISS' | 'LOCATION_ENABLED' | 'RETRY' | 'SCREEN_BLUR';
monitorConnection: 'DISMISS' | 'SCREEN_BLUR' | 'xstate.init';
requestBluetooth: 'BLUETOOTH_STATE_DISABLED';
requestNearByDevicesPermission: 'NEARBY_DISABLED';
requestToEnableLocationPermission: 'LOCATION_DISABLED';
sendVc: 'ACCEPT_REQUEST' | 'CHECK_FLOW_TYPE' | 'FACE_VALID';
startConnection: 'SCAN';
};
matchesStates:
| 'bluetoothDenied'
| 'bluetoothPermissionDenied'
| 'checkBluetoothPermission'
| 'checkBluetoothPermission.checking'
| 'checkBluetoothPermission.enabled'
| 'checkBluetoothState'
| 'checkBluetoothState.checking'
| 'checkBluetoothState.enabled'
| 'checkBluetoothState.requesting'
| 'checkFaceAuthConsent'
| 'checkNearbyDevicesPermission'
| 'checkNearbyDevicesPermission.checking'
| 'checkNearbyDevicesPermission.enabled'
| 'checkNearbyDevicesPermission.requesting'
| 'checkStorage'
| 'checkingLocationState'
| 'checkingLocationState.LocationPermissionRationale'
| 'checkingLocationState.checkLocationService'
| 'checkingLocationState.checkingPermissionStatus'
| 'checkingLocationState.denied'
| 'checkingLocationState.disabled'
| 'checkingLocationState.requestToEnableLocation'
| 'clearingConnection'
| 'connecting'
| 'connecting.inProgress'
| 'connecting.timeout'
| 'decodeQuickShareData'
| 'disconnectDevice'
| 'disconnected'
| 'findingConnection'
| 'handlingBleError'
| 'inactive'
| 'invalid'
| 'loadVCS'
| 'loadVCS.idle'
| 'loadVCS.navigatingToHome'
| 'nearByDevicesPermissionDenied'
| 'recheckBluetoothState'
| 'recheckBluetoothState.checking'
| 'recheckBluetoothState.enabled'
| 'restrictSharingVc'
| 'reviewing'
| 'reviewing.accepted'
| 'reviewing.cancelling'
| 'reviewing.checkFaceAuthConsentForMiniView'
| 'reviewing.disconnect'
| 'reviewing.faceVerificationConsent'
| 'reviewing.idle'
| 'reviewing.invalidIdentity'
| 'reviewing.navigateToHistory'
| 'reviewing.rejected'
| 'reviewing.selectingVc'
| 'reviewing.sendingVc'
| 'reviewing.sendingVc.inProgress'
| 'reviewing.sendingVc.sent'
| 'reviewing.sendingVc.timeout'
| 'reviewing.verifyingIdentity'
| 'showQrLogin'
| 'showQrLogin.idle'
| 'showQrLogin.navigatingToHistory'
| 'showQrLogin.storing'
| 'startPermissionCheck'
| {
checkBluetoothPermission?: 'checking' | 'enabled';
checkBluetoothState?: 'checking' | 'enabled' | 'requesting';
checkNearbyDevicesPermission?: 'checking' | 'enabled' | 'requesting';
checkingLocationState?:
| 'LocationPermissionRationale'
| 'checkLocationService'
| 'checkingPermissionStatus'
| 'denied'
| 'disabled'
| 'requestToEnableLocation';
connecting?: 'inProgress' | 'timeout';
loadVCS?: 'idle' | 'navigatingToHome';
recheckBluetoothState?: 'checking' | 'enabled';
reviewing?:
| 'accepted'
| 'cancelling'
| 'checkFaceAuthConsentForMiniView'
| 'disconnect'
| 'faceVerificationConsent'
| 'idle'
| 'invalidIdentity'
| 'navigateToHistory'
| 'rejected'
| 'selectingVc'
| 'sendingVc'
| 'verifyingIdentity'
| {sendingVc?: 'inProgress' | 'sent' | 'timeout'};
showQrLogin?: 'idle' | 'navigatingToHistory' | 'storing';
};
tags: never;
}

View File

@@ -1,16 +1,16 @@
import { CameraCapturedPicture } from "expo-camera";
import { EmitterSubscription } from "react-native";
import { ActorRefFrom } from "xstate";
import { createModel } from "xstate/lib/model";
import { DeviceInfo } from "../../../components/DeviceInfoList";
import { AppServices } from "../../../shared/GlobalContext";
import { VCShareFlowType } from "../../../shared/Utils";
import { qrLoginMachine } from "../../QrLogin/QrLoginMachine";
import { VC } from "../../VerifiableCredential/VCMetaMachine/vc";
import { ActivityLogType } from "../../activityLog";
import { BLEError } from "../types";
import {CameraCapturedPicture} from 'expo-camera';
import {EmitterSubscription} from 'react-native';
import {ActorRefFrom} from 'xstate';
import {createModel} from 'xstate/lib/model';
import {DeviceInfo} from '../../../components/DeviceInfoList';
import {AppServices} from '../../../shared/GlobalContext';
import {VCShareFlowType} from '../../../shared/Utils';
import {qrLoginMachine} from '../../QrLogin/QrLoginMachine';
import {VC} from '../../VerifiableCredential/VCMetaMachine/vc';
import {ActivityLogType} from '../../activityLog';
import {BLEError} from '../types';
const ScanEvents ={
const ScanEvents = {
SELECT_VC: (vc: VC, flowType: string) => ({vc, flowType}),
SCAN: (params: string) => ({params}),
ACCEPT_REQUEST: () => ({}),
@@ -55,30 +55,30 @@ const ScanEvents ={
}),
ALLOWED: () => ({}),
DENIED: () => ({}),
}
};
export const ScanModel = createModel(
{
serviceRefs: {} as AppServices,
senderInfo: {} as DeviceInfo,
receiverInfo: {} as DeviceInfo,
selectedVc: {} as VC,
bleError: {} as BLEError,
loggers: [] as EmitterSubscription[],
vcName: '',
flowType: VCShareFlowType.SIMPLE_SHARE,
verificationImage: {} as CameraCapturedPicture,
openId4VpUri: '',
shareLogType: '' as ActivityLogType,
QrLoginRef: {} as ActorRefFrom<typeof qrLoginMachine>,
showQuickShareSuccessBanner: false,
linkCode: '',
quickShareData: {},
showFaceAuthConsent: true as boolean,
readyForBluetoothStateCheck: false,
showFaceCaptureSuccessBanner: false,
},
{
events: ScanEvents,
},
);
{
serviceRefs: {} as AppServices,
senderInfo: {} as DeviceInfo,
receiverInfo: {} as DeviceInfo,
selectedVc: {} as VC,
bleError: {} as BLEError,
loggers: [] as EmitterSubscription[],
vcName: '',
flowType: VCShareFlowType.SIMPLE_SHARE,
verificationImage: {} as CameraCapturedPicture,
openId4VpUri: '',
shareLogType: '' as ActivityLogType,
QrLoginRef: {} as ActorRefFrom<typeof qrLoginMachine>,
showQuickShareSuccessBanner: false,
linkCode: '',
quickShareData: {},
showFaceAuthConsent: true as boolean,
readyForBluetoothStateCheck: false,
showFaceCaptureSuccessBanner: false,
},
{
events: ScanEvents,
},
);

View File

@@ -53,11 +53,11 @@ export function selectIsScanning(state: State) {
}
export function selectIsQuickShareDone(state: State) {
return state.matches('loadVCS.navigatingToHome');
return state.matches('loadVCS.navigatingToHome');
}
export function selectShowQuickShareSuccessBanner(state: State) {
return state.context.showQuickShareSuccessBanner
return state.context.showQuickShareSuccessBanner;
}
export function selectIsConnecting(state: State) {
return state.matches('connecting.inProgress');

View File

@@ -1,5 +1,5 @@
import {WalletDataEvent} from '@mosip/tuvali/lib/typescript/types/events';
import { isLocationEnabled } from "react-native-device-info";
import {isLocationEnabled} from 'react-native-device-info';
import Storage from '../../../shared/storage';
import BluetoothStateManager from 'react-native-bluetooth-state-manager';
import tuvali from '@mosip/tuvali';
@@ -12,186 +12,186 @@ import {
RESULTS,
} from 'react-native-permissions';
import {subscribe} from '../../../shared/openIdBLE/walletEventHandler';
import { requestLocationPermission, checkLocationPermissionStatus } from "../../../shared/location";
import { isIOS } from "../../../shared/constants";
import {
requestLocationPermission,
checkLocationPermissionStatus,
} from '../../../shared/location';
import {isIOS} from '../../../shared/constants';
const {wallet, EventTypes, VerificationStatus} = tuvali;
export const ScanServices=(model:any)=>{
return { checkBluetoothPermission: () => async callback => {
// wait a bit for animation to finish when app becomes active
await new Promise(resolve => setTimeout(resolve, 250));
try {
// Passing Granted for android since permission status is always granted even if its denied.
let response: PermissionStatus = RESULTS.GRANTED;
export const ScanServices = (model: any) => {
return {
checkBluetoothPermission: () => async callback => {
// wait a bit for animation to finish when app becomes active
await new Promise(resolve => setTimeout(resolve, 250));
try {
// Passing Granted for android since permission status is always granted even if its denied.
let response: PermissionStatus = RESULTS.GRANTED;
if (isIOS()) {
response = await check(PERMISSIONS.IOS.BLUETOOTH_PERIPHERAL);
}
if (response === RESULTS.GRANTED) {
callback(model.events.BLUETOOTH_PERMISSION_ENABLED());
} else {
callback(model.events.BLUETOOTH_PERMISSION_DENIED());
}
} catch (e) {
console.error(e);
if (isIOS()) {
response = await check(PERMISSIONS.IOS.BLUETOOTH_PERIPHERAL);
}
},
checkBluetoothState: () => callback => {
const subscription = BluetoothStateManager.onStateChange(state => {
if (state === 'PoweredOn') {
callback(model.events.BLUETOOTH_STATE_ENABLED());
} else {
callback(model.events.BLUETOOTH_STATE_DISABLED());
}
}, true);
return () => subscription.remove();
},
requestBluetooth: () => callback => {
BluetoothStateManager.requestToEnable()
.then(() => callback(model.events.BLUETOOTH_STATE_ENABLED()))
.catch(() => callback(model.events.BLUETOOTH_STATE_DISABLED()));
},
requestToEnableLocationPermission: () => callback => {
requestLocationPermission(
() => callback(model.events.LOCATION_ENABLED()),
() => callback(model.events.LOCATION_DISABLED()),
);
},
monitorConnection: () => callback => {
const walletErrorCodePrefix = 'TVW';
const subscription = wallet.handleDataEvents(event => {
if (event.type === EventTypes.onDisconnected) {
callback({type: 'DISCONNECT'});
}
if (
event.type === EventTypes.onError &&
event.code.includes(walletErrorCodePrefix)
) {
callback({
type: 'BLE_ERROR',
bleError: {message: event.message, code: event.code},
});
console.error('BLE Exception: ' + event.message);
}
});
return () => subscription.remove();
},
checkNearByDevicesPermission: () => callback => {
checkMultiple([
PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
])
.then(response => {
if (
response[PERMISSIONS.ANDROID.BLUETOOTH_ADVERTISE] ===
RESULTS.GRANTED &&
response[PERMISSIONS.ANDROID.BLUETOOTH_CONNECT] ===
RESULTS.GRANTED
) {
callback(model.events.NEARBY_ENABLED());
} else {
callback(model.events.NEARBY_DISABLED());
}
})
.catch(err => {
callback(model.events.NEARBY_DISABLED());
});
},
requestNearByDevicesPermission: () => callback => {
requestMultiple([
PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
])
.then(response => {
if (
response[PERMISSIONS.ANDROID.BLUETOOTH_SCAN] ===
RESULTS.GRANTED &&
response[PERMISSIONS.ANDROID.BLUETOOTH_CONNECT] ===
RESULTS.GRANTED
) {
callback(model.events.NEARBY_ENABLED());
} else {
callback(model.events.NEARBY_DISABLED());
}
})
.catch(err => {
callback(model.events.NEARBY_DISABLED());
});
},
checkLocationPermission: () => callback => {
checkLocationPermissionStatus(
() => callback(model.events.LOCATION_ENABLED()),
() => callback(model.events.LOCATION_DISABLED()),
);
},
checkLocationStatus: () => async callback => {
const isEnabled: boolean = await isLocationEnabled();
if (isEnabled) {
callback(model.events.LOCATION_ENABLED());
if (response === RESULTS.GRANTED) {
callback(model.events.BLUETOOTH_PERMISSION_ENABLED());
} else {
callback(model.events.LOCATION_DISABLED());
callback(model.events.BLUETOOTH_PERMISSION_DENIED());
}
},
} catch (e) {
console.error(e);
}
},
startConnection: (context:any) => callback => {
wallet.startConnection(context.openId4VpUri);
const statusCallback = (event: WalletDataEvent) => {
if (event.type === EventTypes.onSecureChannelEstablished) {
callback({type: 'CONNECTED'});
}
};
const subscription = subscribe(statusCallback);
return () => subscription?.remove();
},
sendVc: context => callback => {
const statusCallback = (event: WalletDataEvent) => {
if (event.type === EventTypes.onDataSent) {
callback({type: 'VC_SENT'});
} else if (event.type === EventTypes.onVerificationStatusReceived) {
callback({
type:
event.status === VerificationStatus.ACCEPTED
? 'VC_ACCEPTED'
: 'VC_REJECTED',
});
}
};
wallet.sendData(
JSON.stringify({
...context.selectedVc,
}),
);
const subscription = subscribe(statusCallback);
return () => subscription?.remove();
},
disconnect: () => () => {
try {
console.log("inside wallet disconnect");
wallet.disconnect();
} catch (e) {
// pass
checkBluetoothState: () => callback => {
const subscription = BluetoothStateManager.onStateChange(state => {
if (state === 'PoweredOn') {
callback(model.events.BLUETOOTH_STATE_ENABLED());
} else {
callback(model.events.BLUETOOTH_STATE_DISABLED());
}
},
}, true);
return () => subscription.remove();
},
checkStorageAvailability: () => async () => {
return Promise.resolve(
Storage.isMinimumLimitReached('minStorageRequiredForAuditEntry'),
);
},
};
}
requestBluetooth: () => callback => {
BluetoothStateManager.requestToEnable()
.then(() => callback(model.events.BLUETOOTH_STATE_ENABLED()))
.catch(() => callback(model.events.BLUETOOTH_STATE_DISABLED()));
},
requestToEnableLocationPermission: () => callback => {
requestLocationPermission(
() => callback(model.events.LOCATION_ENABLED()),
() => callback(model.events.LOCATION_DISABLED()),
);
},
monitorConnection: () => callback => {
const walletErrorCodePrefix = 'TVW';
const subscription = wallet.handleDataEvents(event => {
if (event.type === EventTypes.onDisconnected) {
callback({type: 'DISCONNECT'});
}
if (
event.type === EventTypes.onError &&
event.code.includes(walletErrorCodePrefix)
) {
callback({
type: 'BLE_ERROR',
bleError: {message: event.message, code: event.code},
});
console.error('BLE Exception: ' + event.message);
}
});
return () => subscription.remove();
},
checkNearByDevicesPermission: () => callback => {
checkMultiple([
PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
])
.then(response => {
if (
response[PERMISSIONS.ANDROID.BLUETOOTH_ADVERTISE] ===
RESULTS.GRANTED &&
response[PERMISSIONS.ANDROID.BLUETOOTH_CONNECT] === RESULTS.GRANTED
) {
callback(model.events.NEARBY_ENABLED());
} else {
callback(model.events.NEARBY_DISABLED());
}
})
.catch(err => {
callback(model.events.NEARBY_DISABLED());
});
},
requestNearByDevicesPermission: () => callback => {
requestMultiple([
PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
])
.then(response => {
if (
response[PERMISSIONS.ANDROID.BLUETOOTH_SCAN] === RESULTS.GRANTED &&
response[PERMISSIONS.ANDROID.BLUETOOTH_CONNECT] === RESULTS.GRANTED
) {
callback(model.events.NEARBY_ENABLED());
} else {
callback(model.events.NEARBY_DISABLED());
}
})
.catch(err => {
callback(model.events.NEARBY_DISABLED());
});
},
checkLocationPermission: () => callback => {
checkLocationPermissionStatus(
() => callback(model.events.LOCATION_ENABLED()),
() => callback(model.events.LOCATION_DISABLED()),
);
},
checkLocationStatus: () => async callback => {
const isEnabled: boolean = await isLocationEnabled();
if (isEnabled) {
callback(model.events.LOCATION_ENABLED());
} else {
callback(model.events.LOCATION_DISABLED());
}
},
startConnection: (context: any) => callback => {
wallet.startConnection(context.openId4VpUri);
const statusCallback = (event: WalletDataEvent) => {
if (event.type === EventTypes.onSecureChannelEstablished) {
callback({type: 'CONNECTED'});
}
};
const subscription = subscribe(statusCallback);
return () => subscription?.remove();
},
sendVc: context => callback => {
const statusCallback = (event: WalletDataEvent) => {
if (event.type === EventTypes.onDataSent) {
callback({type: 'VC_SENT'});
} else if (event.type === EventTypes.onVerificationStatusReceived) {
callback({
type:
event.status === VerificationStatus.ACCEPTED
? 'VC_ACCEPTED'
: 'VC_REJECTED',
});
}
};
wallet.sendData(
JSON.stringify({
...context.selectedVc,
}),
);
const subscription = subscribe(statusCallback);
return () => subscription?.remove();
},
disconnect: () => () => {
try {
console.log('inside wallet disconnect');
wallet.disconnect();
} catch (e) {
// pass
}
},
checkStorageAvailability: () => async () => {
return Promise.resolve(
Storage.isMinimumLimitReached('minStorageRequiredForAuditEntry'),
);
},
};
};

View File

@@ -1,48 +1,77 @@
// This file was automatically generated. Edits will be overwritten
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"done.invoke._store": { type: "done.invoke._store"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.store.resettingStorage:invocation[0]": { type: "done.invoke.store.resettingStorage:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"error.platform._store": { type: "error.platform._store"; data: unknown };
"xstate.init": { type: "xstate.init" };
};
invokeSrcNameMap: {
"checkStorageInitialisedOrNot": "done.invoke.store.checkStorageInitialisation:invocation[0]";
"clear": "done.invoke.store.resettingStorage:invocation[0]";
"generateEncryptionKey": "done.invoke.store.generatingEncryptionKey:invocation[0]";
"getEncryptionKey": "done.invoke.store.gettingEncryptionKey:invocation[0]";
"hasAndroidEncryptionKey": "done.invoke.store.checkEncryptionKey:invocation[0]";
"store": "done.invoke._store";
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
"forwardStoreRequest": "APPEND" | "CLEAR" | "EXPORT" | "GET" | "GET_VCS_DATA" | "PREPEND" | "REMOVE" | "REMOVE_ITEMS" | "REMOVE_VC_METADATA" | "RESTORE_BACKUP" | "SET" | "UPDATE";
"notifyParent": "KEY_RECEIVED" | "READY" | "done.invoke.store.resettingStorage:invocation[0]";
"setEncryptionKey": "KEY_RECEIVED";
};
eventsCausingDelays: {
};
eventsCausingGuards: {
"isCustomSecureKeystore": "KEY_RECEIVED";
};
eventsCausingServices: {
"checkStorageInitialisedOrNot": "ERROR";
"clear": "KEY_RECEIVED";
"generateEncryptionKey": "ERROR" | "IGNORE" | "READY";
"getEncryptionKey": "TRY_AGAIN";
"hasAndroidEncryptionKey": never;
"store": "KEY_RECEIVED" | "READY" | "done.invoke.store.resettingStorage:invocation[0]";
};
matchesStates: "checkEncryptionKey" | "checkStorageInitialisation" | "failedReadingKey" | "generatingEncryptionKey" | "gettingEncryptionKey" | "ready" | "resettingStorage";
tags: never;
}
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'done.invoke._store': {
type: 'done.invoke._store';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.store.resettingStorage:invocation[0]': {
type: 'done.invoke.store.resettingStorage:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'error.platform._store': {type: 'error.platform._store'; data: unknown};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
checkStorageInitialisedOrNot: 'done.invoke.store.checkStorageInitialisation:invocation[0]';
clear: 'done.invoke.store.resettingStorage:invocation[0]';
generateEncryptionKey: 'done.invoke.store.generatingEncryptionKey:invocation[0]';
getEncryptionKey: 'done.invoke.store.gettingEncryptionKey:invocation[0]';
hasAndroidEncryptionKey: 'done.invoke.store.checkEncryptionKey:invocation[0]';
store: 'done.invoke._store';
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
forwardStoreRequest:
| 'APPEND'
| 'CLEAR'
| 'EXPORT'
| 'GET'
| 'GET_VCS_DATA'
| 'PREPEND'
| 'REMOVE'
| 'REMOVE_ITEMS'
| 'REMOVE_VC_METADATA'
| 'RESTORE_BACKUP'
| 'SET'
| 'UPDATE';
notifyParent:
| 'KEY_RECEIVED'
| 'READY'
| 'done.invoke.store.resettingStorage:invocation[0]';
setEncryptionKey: 'KEY_RECEIVED';
};
eventsCausingDelays: {};
eventsCausingGuards: {
isCustomSecureKeystore: 'KEY_RECEIVED';
};
eventsCausingServices: {
checkStorageInitialisedOrNot: 'ERROR';
clear: 'KEY_RECEIVED';
generateEncryptionKey: 'ERROR' | 'IGNORE' | 'READY';
getEncryptionKey: 'TRY_AGAIN';
hasAndroidEncryptionKey: never;
store:
| 'KEY_RECEIVED'
| 'READY'
| 'done.invoke.store.resettingStorage:invocation[0]';
};
matchesStates:
| 'checkEncryptionKey'
| 'checkStorageInitialisation'
| 'failedReadingKey'
| 'generatingEncryptionKey'
| 'gettingEncryptionKey'
| 'ready'
| 'resettingStorage';
tags: never;
}

View File

@@ -17,7 +17,7 @@ const model = createModel(
myVcs: {} as ActorRefFrom<typeof MyVcsTabMachine>,
receivedVcs: {} as ActorRefFrom<typeof ReceivedVcsTabMachine>,
},
selectedVc: ActorRefFrom<typeof VCItemMachine>,
selectedVc: null as ActorRefFrom<typeof VCItemMachine> | null,
activeTab: 0,
},
{

View File

@@ -1,40 +1,65 @@
// This file was automatically generated. Edits will be overwritten
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"done.invoke.HomeScreen.tabs.checkStorage:invocation[0]": { type: "done.invoke.HomeScreen.tabs.checkStorage:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"xstate.after(100)#HomeScreen.tabs.init": { type: "xstate.after(100)#HomeScreen.tabs.init" };
"xstate.init": { type: "xstate.init" };
};
invokeSrcNameMap: {
"checkStorageAvailability": "done.invoke.HomeScreen.tabs.checkStorage:invocation[0]";
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
"resetSelectedVc": "DISMISS_MODAL" | "xstate.init";
"sendAddEvent": "DOWNLOAD_ID";
"setSelectedVc": "VIEW_VC";
"spawnTabActors": "xstate.init";
};
eventsCausingDelays: {
};
eventsCausingGuards: {
"isMinimumStorageLimitReached": "done.invoke.HomeScreen.tabs.checkStorage:invocation[0]";
};
eventsCausingServices: {
"checkStorageAvailability": "GOTO_ISSUERS";
"issuersMachine": "done.invoke.HomeScreen.tabs.checkStorage:invocation[0]";
};
matchesStates: "modals" | "modals.none" | "modals.viewingVc" | "tabs" | "tabs.checkStorage" | "tabs.gotoIssuers" | "tabs.history" | "tabs.idle" | "tabs.init" | "tabs.myVcs" | "tabs.receivedVcs" | "tabs.storageLimitReached" | { "modals"?: "none" | "viewingVc";
"tabs"?: "checkStorage" | "gotoIssuers" | "history" | "idle" | "init" | "myVcs" | "receivedVcs" | "storageLimitReached"; };
tags: never;
}
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'done.invoke.HomeScreen.tabs.checkStorage:invocation[0]': {
type: 'done.invoke.HomeScreen.tabs.checkStorage:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'xstate.after(100)#HomeScreen.tabs.init': {
type: 'xstate.after(100)#HomeScreen.tabs.init';
};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
checkStorageAvailability: 'done.invoke.HomeScreen.tabs.checkStorage:invocation[0]';
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
resetSelectedVc: 'DISMISS_MODAL' | 'xstate.init';
sendAddEvent: 'DOWNLOAD_ID';
setSelectedVc: 'VIEW_VC';
spawnTabActors: 'xstate.init';
};
eventsCausingDelays: {};
eventsCausingGuards: {
isMinimumStorageLimitReached: 'done.invoke.HomeScreen.tabs.checkStorage:invocation[0]';
};
eventsCausingServices: {
checkStorageAvailability: 'GOTO_ISSUERS';
issuersMachine: 'done.invoke.HomeScreen.tabs.checkStorage:invocation[0]';
};
matchesStates:
| 'modals'
| 'modals.none'
| 'modals.viewingVc'
| 'tabs'
| 'tabs.checkStorage'
| 'tabs.gotoIssuers'
| 'tabs.history'
| 'tabs.idle'
| 'tabs.init'
| 'tabs.myVcs'
| 'tabs.receivedVcs'
| 'tabs.storageLimitReached'
| {
modals?: 'none' | 'viewingVc';
tabs?:
| 'checkStorage'
| 'gotoIssuers'
| 'history'
| 'idle'
| 'init'
| 'myVcs'
| 'receivedVcs'
| 'storageLimitReached';
};
tags: never;
}

View File

@@ -1,5 +1,10 @@
import React from 'react';
import {I18nManager, KeyboardAvoidingView, Dimensions} from 'react-native';
import {
I18nManager,
KeyboardAvoidingView,
Dimensions,
View,
} from 'react-native';
import {Icon, Input} from 'react-native-elements';
import {Button, Column, Row, Text} from '../../../components/ui';
import {Modal} from '../../../components/ui/Modal';
@@ -75,8 +80,6 @@ export const GetIdInputModal: React.FC<GetIdInputModalProps> = props => {
rightIcon={
<CustomTooltip
testID="GetIdInputToolTip"
title={t('toolTipTitle')}
description={t(`toolTipDescription`)}
width={Dimensions.get('screen').width * 0.87}
height={Dimensions.get('screen').height * 0.25}
triggerComponent={
@@ -87,6 +90,18 @@ export const GetIdInputModal: React.FC<GetIdInputModalProps> = props => {
color={Theme.Colors.tooltipIcon}
/>
}
triggerComponentStyles={{width: 32}}
toolTipContent={
<Column>
<Text weight="semibold">{t('toolTipTitle')}</Text>
<View style={Theme.Styles.tooltipHrLine}></View>
<Text
weight="regular"
style={Theme.Styles.tooltipContentDescription}>
{t(`toolTipDescription`)}
</Text>
</Column>
}
/>
}
errorStyle={{color: Theme.Colors.errorMessage}}

View File

@@ -2,12 +2,17 @@
export interface Typegen0 {
'@@xstate/typegen': true;
'internalEvents': {
internalEvents: {
'done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]': {
type: 'done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]': {
type: 'done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.GetVcModal.requestingUinVid:invocation[0]': {
type: 'done.invoke.GetVcModal.requestingUinVid:invocation[0]';
data: unknown;
@@ -17,6 +22,10 @@ export interface Typegen0 {
type: 'error.platform.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]';
data: unknown;
};
'error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]': {
type: 'error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]';
data: unknown;
};
'error.platform.GetVcModal.requestingUinVid:invocation[0]': {
type: 'error.platform.GetVcModal.requestingUinVid:invocation[0]';
data: unknown;
@@ -24,38 +33,46 @@ export interface Typegen0 {
'xstate.after(100)#GetVcModal.acceptingIdInput.focusing': {
type: 'xstate.after(100)#GetVcModal.acceptingIdInput.focusing';
};
'xstate.init': { type: 'xstate.init' };
'xstate.init': {type: 'xstate.init'};
};
'invokeSrcNameMap': {
requestOtp: 'done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]';
invokeSrcNameMap: {
requestOtp:
| 'done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]'
| 'done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]';
requestingUinVid: 'done.invoke.GetVcModal.requestingUinVid:invocation[0]';
};
'missingImplementations': {
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
'eventsCausingActions': {
eventsCausingActions: {
clearIdError: 'INPUT_ID';
clearOtp:
| 'DISMISS'
| 'done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]'
| 'error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]'
| 'error.platform.GetVcModal.requestingUinVid:invocation[0]'
| 'xstate.init';
focusInput:
| 'INPUT_ID'
| 'VALIDATE_INPUT'
| 'error.platform.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]'
| 'error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]'
| 'error.platform.GetVcModal.requestingUinVid:invocation[0]'
| 'xstate.after(100)#GetVcModal.acceptingIdInput.focusing';
forwardToParent: 'DISMISS';
resetIdInputRef: 'DISMISS';
setEmail:
| 'done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]'
| 'done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]';
setIconColorActivate: 'ACTIVATE_ICON_COLOR';
setIconColorDeactivate: 'DEACTIVATE_ICON_COLOR';
setId: 'INPUT_ID';
setIdBackendError:
| 'error.platform.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]'
| 'error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]'
| 'error.platform.GetVcModal.requestingUinVid:invocation[0]';
setIdErrorEmpty: 'VALIDATE_INPUT';
setIdErrorWrongFormat: 'VALIDATE_INPUT';
@@ -63,25 +80,29 @@ export interface Typegen0 {
setIndividualId: 'done.invoke.GetVcModal.requestingUinVid:invocation[0]';
setOtp: 'INPUT_OTP';
setOtpError: 'error.platform.GetVcModal.requestingUinVid:invocation[0]';
setPhoneNumber:
| 'done.invoke.GetVcModal.acceptingIdInput.requestingOtp:invocation[0]'
| 'done.invoke.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]';
setTransactionId:
| 'DISMISS'
| 'error.platform.GetVcModal.acceptingOtpInput.resendOTP:invocation[0]'
| 'error.platform.GetVcModal.requestingUinVid:invocation[0]'
| 'xstate.init';
};
'eventsCausingDelays': {};
'eventsCausingGuards': {
eventsCausingDelays: {};
eventsCausingGuards: {
isEmptyId: 'VALIDATE_INPUT';
isIdInvalid: 'error.platform.GetVcModal.requestingUinVid:invocation[0]';
isWrongIdFormat: 'VALIDATE_INPUT';
};
'eventsCausingServices': {
eventsCausingServices: {
AddVcModal:
| 'INPUT_ID'
| 'xstate.after(100)#GetVcModal.acceptingIdInput.focusing';
requestOtp: 'VALIDATE_INPUT';
requestOtp: 'RESEND_OTP' | 'VALIDATE_INPUT';
requestingUinVid: 'INPUT_OTP';
};
'matchesStates':
matchesStates:
| 'acceptingIdInput'
| 'acceptingIdInput.focusing'
| 'acceptingIdInput.idle'
@@ -92,6 +113,8 @@ export interface Typegen0 {
| 'acceptingIdInput.rendering'
| 'acceptingIdInput.requestingOtp'
| 'acceptingOtpInput'
| 'acceptingOtpInput.idle'
| 'acceptingOtpInput.resendOTP'
| 'done'
| 'requestingUinVid'
| {
@@ -101,7 +124,8 @@ export interface Typegen0 {
| 'invalid'
| 'rendering'
| 'requestingOtp'
| { invalid?: 'backend' | 'empty' | 'format' };
| {invalid?: 'backend' | 'empty' | 'format'};
acceptingOtpInput?: 'idle' | 'resendOTP';
};
'tags': never;
tags: never;
}

View File

@@ -12,6 +12,7 @@ import {
TextInput,
TouchableOpacity,
Dimensions,
View,
} from 'react-native';
import {
individualId,
@@ -109,8 +110,6 @@ export const IdInputModal: React.FC<IdInputModalProps> = props => {
rightIcon={
<CustomTooltip
testID="IdInputToolTip"
title={t('toolTipTitle', {idType: controller.idType})}
description={t(`toolTip${controller.idType}Description`)}
width={Dimensions.get('screen').width * 0.85}
height={Dimensions.get('screen').height * 0.18}
triggerComponent={
@@ -121,6 +120,20 @@ export const IdInputModal: React.FC<IdInputModalProps> = props => {
color={Theme.Colors.tooltipIcon}
/>
}
triggerComponentStyles={{width: 32}}
toolTipContent={
<Column>
<Text weight="semibold">
{t('toolTipTitle', {idType: controller.idType})}
</Text>
<View style={Theme.Styles.tooltipHrLine}></View>
<Text
weight="regular"
style={Theme.Styles.tooltipContentDescription}>
{t(`toolTip${controller.idType}Description`)}
</Text>
</Column>
}
/>
}
errorStyle={Theme.TextStyles.error}

View File

@@ -10,7 +10,10 @@ import {useTranslation} from 'react-i18next';
import {BANNER_TYPE_SUCCESS, GET_INDIVIDUAL_ID} from '../../shared/constants';
import {MessageOverlay} from '../../components/MessageOverlay';
import {VcItemContainer} from '../../components/VC/VcItemContainer';
import {BannerNotification} from '../../components/BannerNotification';
import {
BannerNotification,
BannerStatusType,
} from '../../components/BannerNotification';
import {
getErrorEventData,
sendErrorEvent,
@@ -203,7 +206,7 @@ export const MyVcsTab: React.FC<HomeScreenTabProps> = props => {
<Column fill style={{display: props.isVisible ? 'flex' : 'none'}}>
{controller.isRequestSuccessful && (
<BannerNotification
type={BANNER_TYPE_SUCCESS}
type={BannerStatusType.SUCCESS}
message={t('downloadingYourCard')}
onClosePress={() => {
controller.RESET_STORE_VC_ITEM_STATUS();

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React, {useEffect, useState} from 'react';
import {Row} from '../../components/ui';
import {Modal} from '../../components/ui/Modal';
import {MessageOverlay} from '../../components/MessageOverlay';
@@ -21,11 +21,52 @@ import {VCMetadata} from '../../shared/VCMetadata';
import {WalletBinding} from './MyVcs/WalletBinding';
import {RemoveVcWarningOverlay} from './MyVcs/RemoveVcWarningOverlay';
import {HistoryTab} from './MyVcs/HistoryTab';
import {getDetailedViewFields} from '../../shared/openId4VCI/Utils';
import {
DETAIL_VIEW_DEFAULT_FIELDS,
isVCLoaded,
} from '../../components/VC/common/VCUtils';
import {ActivityIndicator} from '../../components/ui/ActivityIndicator';
import ShimmerPlaceholder from 'react-native-shimmer-placeholder';
import LinearGradient from 'react-native-linear-gradient';
import {
BannerNotification,
BannerStatus,
} from '../../components/BannerNotification';
export const ViewVcModal: React.FC<ViewVcModalProps> = props => {
const {t} = useTranslation('ViewVcModal');
const controller = useViewVcModal(props);
const profileImage = controller.verifiableCredentialData.face;
const verificationStatus = controller.verificationStatus;
useEffect(() => {
if (controller.isVerificationInProgress) {
controller.SHOW_VERIFICATION_STATUS_BANNER();
}
if (
!controller.verifiableCredentialData.vcMetadata.isVerified &&
!controller.isVerificationInProgress
) {
props.vcItemActor.send({type: 'VERIFY'});
}
}, [controller.verifiableCredentialData.vcMetadata.isVerified]);
let [fields, setFields] = useState([]);
const [wellknown, setWellknown] = useState(null);
const verifiableCredentialData = controller.verifiableCredentialData;
useEffect(() => {
getDetailedViewFields(
verifiableCredentialData?.issuer,
verifiableCredentialData?.wellKnown,
verifiableCredentialData?.credentialTypes,
DETAIL_VIEW_DEFAULT_FIELDS,
).then(response => {
setWellknown(response.wellknown);
setFields(response.fields);
});
}, [verifiableCredentialData?.wellKnown]);
const headerRight = flow => {
return flow === 'downloadedVc' ? (
@@ -43,25 +84,41 @@ export const ViewVcModal: React.FC<ViewVcModalProps> = props => {
/>
}
/>
<Pressable
onPress={() => props.vcItemActor.send('KEBAB_POPUP')}
accessible={false}>
<KebabPopUp
icon={SvgImage.kebabIcon('KebabIcon')}
iconColor={null}
vcMetadata={controller.verifiableCredentialData.vcMetadata}
isVisible={
props.vcItemActor.getSnapshot()?.context
.isMachineInKebabPopupState
}
onDismiss={() => props.vcItemActor.send('DISMISS')}
service={props.vcItemActor}
vcHasImage={profileImage !== undefined}
{isVCLoaded(controller.credential, fields) ? (
<Pressable
onPress={() => props.vcItemActor.send('KEBAB_POPUP')}
accessible={false}>
<KebabPopUp
icon={SvgImage.kebabIcon('KebabIcon')}
vcMetadata={controller.verifiableCredentialData.vcMetadata}
isVisible={
props.vcItemActor.getSnapshot()?.context
.isMachineInKebabPopupState
}
onDismiss={() => props.vcItemActor.send('DISMISS')}
service={props.vcItemActor}
vcHasImage={profileImage !== undefined}
/>
</Pressable>
) : (
<ShimmerPlaceholder
LinearGradient={LinearGradient}
width={35}
height={35}
style={{borderRadius: 5, marginLeft: 2}}
/>
</Pressable>
)}
</Row>
) : undefined;
};
const handleModalDismiss = () => {
props.onDismiss();
if (controller.isVerificationCompleted) {
props.vcItemActor.send('REMOVE_VERIFICATION_STATUS_BANNER');
}
};
return (
<Modal
isVisible={props.isVisible}
@@ -69,17 +126,38 @@ export const ViewVcModal: React.FC<ViewVcModalProps> = props => {
arrowLeft={true}
headerRight={headerRight(props.flow)}
headerTitle={t('title')}
onDismiss={props.onDismiss}
onDismiss={handleModalDismiss}
headerElevation={2}>
<BannerNotificationContainer />
<VcDetailsContainer
credential={controller.credential}
verifiableCredentialData={controller.verifiableCredentialData}
onBinding={controller.addtoWallet}
walletBindingResponse={controller.walletBindingResponse}
activeTab={props.activeTab}
vcHasImage={profileImage !== undefined}
/>
<BannerNotificationContainer showVerificationStatusBanner={false} />
{controller.showVerificationStatusBanner && (
<BannerNotification
type={verificationStatus?.statusType as BannerStatus}
message={t(`VcVerificationBanner:${verificationStatus?.statusType}`, {
vcDetails: `${t(`VcDetails:${verificationStatus?.vcType}`)} ${
verificationStatus?.vcNumber
}`,
})}
onClosePress={controller.RESET_VERIFICATION_STATUS}
key={'reVerificationInProgress'}
testId={'reVerificationInProgress'}
/>
)}
{!isVCLoaded(controller.credential, fields) ? (
<ActivityIndicator />
) : (
<VcDetailsContainer
fields={fields}
wellknown={wellknown}
credential={controller.credential}
verifiableCredentialData={controller.verifiableCredentialData}
onBinding={controller.addtoWallet}
walletBindingResponse={controller.walletBindingResponse}
activeTab={props.activeTab}
vcHasImage={profileImage !== undefined}
/>
)}
{controller.isAcceptingBindingOtp && (
<OtpVerificationModal

View File

@@ -18,6 +18,10 @@ import {
selectWalletBindingInProgress,
selectWalletBindingResponse,
selectWalletBindingSuccess,
selectVerificationStatus,
selectIsVerificationInProgress,
selectShowVerificationStatusBanner,
selectIsVerificationCompleted,
} from '../../machines/VerifiableCredential/VCItemMachine/VCItemSelectors';
import {selectPasscode} from '../../machines/auth';
import {biometricsMachine, selectIsSuccess} from '../../machines/biometrics';
@@ -26,6 +30,7 @@ import {
VCItemMachine,
} from '../../machines/VerifiableCredential/VCItemMachine/VCItemMachine';
import {selectIsAcceptingOtpInput} from './MyVcs/AddVcModalMachine';
import {BannerStatusType} from '../../components/BannerNotification';
export function useViewVcModal({vcItemActor, isVisible}: ViewVcModalProps) {
const [toastVisible, setToastVisible] = useState(false);
@@ -120,6 +125,26 @@ export function useViewVcModal({vcItemActor, isVisible}: ViewVcModalProps) {
inputOtp: (otp: string) => {
netInfoFetch(otp);
},
verificationStatus: useSelector(vcItemActor, selectVerificationStatus),
isVerificationInProgress: useSelector(
vcItemActor,
selectIsVerificationInProgress,
),
isVerificationCompleted: useSelector(
vcItemActor,
selectIsVerificationCompleted,
),
showVerificationStatusBanner: useSelector(
vcItemActor,
selectShowVerificationStatusBanner,
),
RESET_VERIFICATION_STATUS: () =>
vcItemActor.send(VCItemEvents.RESET_VERIFICATION_STATUS()),
SHOW_VERIFICATION_STATUS_BANNER: () =>
vcItemActor.send({
type: 'SHOW_VERIFICATION_STATUS_BANNER',
response: {statusType: BannerStatusType.IN_PROGRESS},
}),
onSuccess,
DISMISS: () => vcItemActor.send(VCItemEvents.DISMISS()),
INPUT_OTP: (otp: string) => vcItemActor.send(VCItemEvents.INPUT_OTP(otp)),

View File

@@ -51,7 +51,7 @@ export const HomeScreenLayout: React.FC<RootRouteProps> = props => {
<View testID="help" style={Theme.HelpScreenStyle.viewStyle}>
<Row crossAlign="center" style={Theme.HelpScreenStyle.rowStyle}>
<View testID="helpIcon" style={Theme.HelpScreenStyle.iconStyle}>
{SvgImage.infoIcon()}
{SvgImage.coloredInfo()}
</View>
<Text testID="helpText" style={Theme.HelpScreenStyle.labelStyle}>
{t('help')}

View File

@@ -1,7 +1,7 @@
import {useSelector} from '@xstate/react';
import {useContext, useState} from 'react';
import {ActorRefFrom} from 'xstate';
import { QrLoginEvents } from '../../machines/QrLogin/QrLoginMachine';
import {QrLoginEvents} from '../../machines/QrLogin/QrLoginMachine';
import {
selectClientName,
selectErrorMessage,
@@ -86,7 +86,9 @@ export function useQrLogin({service}: QrLoginProps) {
service.send(QrLoginEvents.SELECT_VC(vcData));
},
FACE_VERIFICATION_CONSENT: (isDoNotAskAgainChecked: boolean) =>
service.send(QrLoginEvents.FACE_VERIFICATION_CONSENT(isDoNotAskAgainChecked)),
service.send(
QrLoginEvents.FACE_VERIFICATION_CONSENT(isDoNotAskAgainChecked),
),
DISMISS: () => service.send(QrLoginEvents.DISMISS()),
SCANNING_DONE: (qrCode: string) =>
service.send(QrLoginEvents.SCANNING_DONE(qrCode)),

View File

@@ -12,9 +12,9 @@ import {Loader} from '../../components/ui/Loader';
import {VCShareFlowType} from '../../shared/Utils';
import {VerifyIdentityOverlay} from '../VerifyIdentityOverlay';
import {SvgImage} from '../../components/ui/svg';
import {BANNER_TYPE_SUCCESS} from '../../shared/constants';
import {View, I18nManager} from 'react-native';
import {Text} from './../../components/ui';
import { BannerStatusType } from '../../components/BannerNotification';
const ScanStack = createNativeStackNavigator();
@@ -42,7 +42,7 @@ export const ScanLayout: React.FC = () => {
showBanner={controller.isFaceIdentityVerified}
bannerMessage={t('ScanScreen:postFaceCapture:captureSuccessMessage')}
onBannerClose={controller.CLOSE_BANNER}
bannerType={BANNER_TYPE_SUCCESS}
bannerType={BannerStatusType.SUCCESS}
bannerTestID={'faceVerificationSuccess'}
/>
);

View File

@@ -16,8 +16,8 @@ import {BannerNotificationContainer} from '../../components/BannerNotificationCo
import {SharingStatusModal} from './SharingStatusModal';
import {SvgImage} from '../../components/ui/svg';
import {LocationPermissionRational} from './LocationPermissionRational';
import { FaceVerificationAlertOverlay } from './FaceVerificationAlertOverlay';
import { useSendVcScreen } from './SendVcScreenController';
import {FaceVerificationAlertOverlay} from './FaceVerificationAlertOverlay';
import {useSendVcScreen} from './SendVcScreenController';
export const ScanScreen: React.FC = () => {
const {t} = useTranslation('ScanScreen');
@@ -39,8 +39,11 @@ export const ScanScreen: React.FC = () => {
// TODO(kludge): skip running this hook on every render
useEffect(() => {
if (scanScreenController.isStartPermissionCheck && !scanScreenController.isEmpty)
scanScreenController.START_PERMISSION_CHECK();
if (
scanScreenController.isStartPermissionCheck &&
!scanScreenController.isEmpty
)
scanScreenController.START_PERMISSION_CHECK();
});
useEffect(() => {
@@ -142,7 +145,10 @@ export const ScanScreen: React.FC = () => {
function qrScannerComponent() {
return (
<Column crossAlign="center" margin="0 0 0 -6">
<QrScanner onQrFound={scanScreenController.SCAN} title={t('scanningGuide')} />
<QrScanner
onQrFound={scanScreenController.SCAN}
title={t('scanningGuide')}
/>
</Column>
);
}
@@ -171,7 +177,10 @@ export const ScanScreen: React.FC = () => {
/>
);
}
if (scanScreenController.isLocationDisabled || scanScreenController.isLocationDenied) {
if (
scanScreenController.isLocationDisabled ||
scanScreenController.isLocationDenied
) {
return allowLocationComponent();
}
@@ -225,7 +234,7 @@ export const ScanScreen: React.FC = () => {
onConfirm={sendVcScreenController.FACE_VERIFICATION_CONSENT}
close={sendVcScreenController.DISMISS}
/>
<Centered
<Centered
padding="24 0"
align="space-evenly"
backgroundColor={Theme.Colors.whiteBackgroundColor}>

View File

@@ -22,10 +22,8 @@ import {
selectIsStartPermissionCheck,
selectIsLocationPermissionRationale,
} from '../../machines/bleShare/commonSelectors';
import {
ScanEvents,
} from '../../machines/bleShare/scan/scanMachine';
import { selectIsMinimumStorageRequiredForAuditEntryLimitReached } from '../../machines/bleShare/scan/scanSelectors';
import {ScanEvents} from '../../machines/bleShare/scan/scanMachine';
import {selectIsMinimumStorageRequiredForAuditEntryLimitReached} from '../../machines/bleShare/scan/scanSelectors';
import {BOTTOM_TAB_ROUTES} from '../../routes/routesConstants';
import {MainBottomTabParamList} from '../../routes/routeTypes';
import {useNavigation, NavigationProp} from '@react-navigation/native';

View File

@@ -15,10 +15,8 @@ import {
selectIsInvalidIdentity,
selectIsVerifyingIdentity,
} from '../../machines/bleShare/commonSelectors';
import {
ScanEvents,
} from '../../machines/bleShare/scan/scanMachine';
import { selectIsFaceVerificationConsent } from '../../machines/bleShare/scan/scanSelectors';
import {ScanEvents} from '../../machines/bleShare/scan/scanMachine';
import {selectIsFaceVerificationConsent} from '../../machines/bleShare/scan/scanSelectors';
import {VCShareFlowType} from '../../shared/Utils';
import {NavigationProp, useNavigation} from '@react-navigation/native';
import {RootRouteProps} from '../../routes';
@@ -64,7 +62,9 @@ export function useSendVcScreen() {
CANCEL: () => scanService.send(ScanEvents.CANCEL()),
ACCEPT_REQUEST: () => scanService.send(ScanEvents.ACCEPT_REQUEST()),
FACE_VERIFICATION_CONSENT: (isDoNotAskAgainChecked: boolean) =>
scanService.send(ScanEvents.FACE_VERIFICATION_CONSENT(isDoNotAskAgainChecked)),
scanService.send(
ScanEvents.FACE_VERIFICATION_CONSENT(isDoNotAskAgainChecked),
),
VERIFY_AND_ACCEPT_REQUEST: () =>
scanService.send(ScanEvents.VERIFY_AND_ACCEPT_REQUEST()),
DISMISS: () => scanService.send(ScanEvents.DISMISS()),

View File

@@ -214,7 +214,7 @@ const BackupAndRestoreScreen: React.FC<BackupAndRestoreProps> = props => {
<View testID="help" style={Theme.HelpScreenStyle.viewStyle}>
<Row crossAlign="center" style={Theme.HelpScreenStyle.rowStyle}>
<View testID="helpIcon" style={Theme.HelpScreenStyle.iconStyle}>
{SvgImage.infoIcon()}
{SvgImage.info()}
</View>
<Text
testID="helpText"

View File

@@ -476,7 +476,7 @@ export default Cloud;
export type ProfileInfo = {
email: string;
picture: string|undefined;
picture: string | undefined;
};
export type SignInResult = {

View File

@@ -14,6 +14,7 @@ export class VCMetadata {
issuer?: string = '';
protocol?: string = '';
timestamp?: string = '';
isVerified: boolean = false;
constructor({
idType = '',
@@ -23,6 +24,7 @@ export class VCMetadata {
issuer = '',
protocol = '',
timestamp = '',
isVerified = false,
} = {}) {
this.idType = idType;
this.requestId = requestId;
@@ -31,6 +33,7 @@ export class VCMetadata {
this.protocol = protocol;
this.issuer = issuer;
this.timestamp = timestamp;
this.isVerified = isVerified;
}
//TODO: Remove any typing and use appropriate typing
@@ -43,6 +46,7 @@ export class VCMetadata {
protocol: vc.protocol,
issuer: vc.issuer,
timestamp: vc.vcMetadata ? vc.vcMetadata.timestamp : vc.timestamp,
isVerified: vc.isVerified,
});
}
@@ -95,6 +99,7 @@ export const getVCMetadata = (context: object) => {
id: context.verifiableCredential?.credential.credentialSubject
.policyNumber,
timestamp: context.timestamp ?? '',
isVerified: context.isVerified ?? false,
});
}
return VCMetadata.fromVC({
@@ -105,5 +110,6 @@ export const getVCMetadata = (context: object) => {
context.verifiableCredential?.credential.credentialSubject,
),
timestamp: context.timestamp ?? '',
isVerified: context.isVerified ?? false,
});
};

View File

@@ -43,14 +43,8 @@ export const APP_ID_LENGTH = 12;
export const SHOW_FACE_AUTH_CONSENT_SHARE_FLOW = 'showFaceAuthConsentShareFlow';
export const SHOW_FACE_AUTH_CONSENT_QR_LOGIN_FLOW='showFaceAuthConsentQrLoginFlow'
//Banner Status
export const BANNER_TYPE_SUCCESS = 'success';
export const BANNER_TYPE_ERROR = 'error';
export const BANNER_TYPE_INFO = 'info';
export const SHOW_FACE_AUTH_CONSENT_QR_LOGIN_FLOW =
'showFaceAuthConsentQrLoginFlow';
// Numbers and Upper case Alphabets without confusing characters like 0, 1, 2, I, O, Z
// prettier-ignore

View File

@@ -15,7 +15,10 @@ import {
import {
BOTTOM_SECTION_FIELDS_WITH_DETAILED_ADDRESS_FIELDS,
DETAIL_VIEW_ADD_ON_FIELDS,
getCredentialDefinition,
} from '../../components/VC/common/VCUtils';
import {getVerifiableCredential} from '../../machines/VerifiableCredential/VCItemMachine/VCItemSelectors';
import {vcVerificationBannerDetails} from '../../components/BannerNotificationContainer';
export const Protocols = {
OpenId4VCI: 'OpenId4VCI',
@@ -41,11 +44,26 @@ export function getIdType(issuer: string | undefined): string {
return 'insuranceCard';
}
export function getVcVerificationDetails(
statusType,
vcMetadata,
verifiableCredential,
): vcVerificationBannerDetails {
return {
statusType: statusType,
vcType: getIDType(
getVerifiableCredential(vcMetadata, verifiableCredential),
),
vcNumber: getVerifiableCredential(vcMetadata, verifiableCredential)
.credentialSubject[`${vcMetadata.idType}`],
};
}
export const ID_TYPE = {
MOSIPVerifiableCredential: i18n.t('VcDetails:nationalCard'),
InsuranceCredential: i18n.t('VcDetails:insuranceCard'),
OpenG2PBeneficiaryVerifiableCredential: i18n.t('VcDetails:beneficiaryCard'),
OpenG2PRegistryVerifiableCredential: i18n.t('VcDetails:socialRegistryCard'),
MOSIPVerifiableCredential: 'nationalCard',
InsuranceCredential: 'insuranceCard',
OpenG2PBeneficiaryVerifiableCredential: 'beneficiaryCard',
OpenG2PRegistryVerifiableCredential: 'socialRegistryCard',
};
export const getIDType = (verifiableCredential: VerifiableCredential) => {
@@ -199,30 +217,30 @@ export const getJWK = async publicKey => {
export const getCredentialIssuersWellKnownConfig = async (
issuer: string,
wellknown: string,
credentialTypes: Object[],
vcCredentialTypes: Object[],
defaultFields: string[],
) => {
let fields: string[] = defaultFields;
let fields: string[] = [];
let response = null;
if (wellknown) {
if (issuer === Issuers.Mosip) {
fields = defaultFields;
} else if (wellknown) {
response = await CACHED_API.fetchIssuerWellknownConfig(issuer, wellknown);
if (!response) {
fields = [];
} else if (response?.credentials_supported[0].order) {
fields = response?.credentials_supported[0].order;
} else {
const supportedCredentialTypes = credentialTypes.filter(
type => type !== 'VerifiableCredential',
);
const selectedCredentialType = supportedCredentialTypes[0];
response?.credentials_supported.filter(credential => {
if (credential.id === selectedCredentialType) {
fields = Object.keys(
credential.credential_definition.credentialSubject,
);
}
});
if (response) {
if (
Array.isArray(response.credentials_supported) &&
response?.credentials_supported[0].order
) {
fields = response?.credentials_supported[0].order;
} else {
const credentialDefinition = getCredentialDefinition(
response,
vcCredentialTypes,
);
fields = credentialDefinition
? Object.keys(credentialDefinition.credentialSubject)
: [];
}
}
}
return {

View File

@@ -113,7 +113,7 @@ function handleResponse(
return verificationResult;
}
const VerificationErrorType = {
export const VerificationErrorType = {
NO_ERROR: '',
TECHNICAL_ERROR: 'technicalError',
RANGE_ERROR: 'RangeError',