[INJIMOB-2670]: Auto Activation Commits (#1810)

* [INJIMOB-2670]: Enable Auto Vc Activation (#1)

* [INJIMOB-2670]: Enable Auto Vc Activation (#1759)

* [INJIMOB-2670]: Hide Success Banner during Auto Activation.

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-2670]: Locales for Auto Activation Error message

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-2670]: Enable Auto Vc Activation and handle error scenarios

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-2670]: Remove activation sections from Help content

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-2670]: Update Event name to be generic

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-2670]: Remove communication details and add default OTP into constants

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

---------

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-2670]: Removing Mosip specific condition for mosipInidividualId

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

---------

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* add spanish language (#2)

Signed-off-by: Sk Mijan Hossain <skmijanhossain@gmail.com>
Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-2670]: Individual Id fix and add prefix to face image (#4)

* [INJIMOB-2670]: Individual Id fix and appending image format for face image.

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-2670]: Add Utils to append Png Base64 Prefix to faceImage.

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

---------

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-2670]: Update artifact Id and App name in fastlane scripts and build.gradle. (#3)

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-2670]: Add enable_auth and remove lilveness_detection in internal-build yml (#5)

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-2670]: Spanish locale updates. (#6)

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-2670]: Liveness detection flag type changed to string

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

---------

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>
Signed-off-by: Sk Mijan Hossain <skmijanhossain@gmail.com>
Co-authored-by: mijan32 <74153970+mijan32@users.noreply.github.com>
This commit is contained in:
balachandarg-tw
2025-02-20 17:15:18 +05:30
committed by GitHub
parent ce187aa109
commit 4633533eb2
41 changed files with 1481 additions and 130 deletions

4
.env
View File

@@ -2,9 +2,9 @@
# eg . npm build android:newlogic --reset-cache
#MIMOTO_HOST=http://mock.mimoto.newlogic.dev
MIMOTO_HOST=https://api.qa-inji.mosip.net
MIMOTO_HOST=https://api.peru-pilot2.mosip.net
ESIGNET_HOST=https://esignet.qa-inji.mosip.net
ESIGNET_HOST=https://esignet.peru-pilot2.mosip.net
OBSRV_HOST = https://dataset-api.telemetry.mosip.net

View File

@@ -12,6 +12,8 @@ elif [[ "$flavor" == "inji" ]]; then
echo "CLIENT_ID=INJI_ORG_KEY" >> $GITHUB_OUTPUT
elif [[ "$flavor" == "mec" ]]; then
echo "CLIENT_ID=MEC_ORG_KEY" >> $GITHUB_OUTPUT
elif [[ "$flavor" == "reniec" ]]; then
echo "CLIENT_ID=RENIEC_ORG_KEY" >> $GITHUB_OUTPUT
else
echo "Error: Invalid flavor '$flavor'"
exit 1

View File

@@ -47,6 +47,7 @@ on:
- collab
- synergy
- mec
- reniec
internal-testers:
description: 'Internal Testers Group'
required: true
@@ -200,4 +201,4 @@ jobs:
# secrets:
# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
# SONAR_ORGANIZATION: ${{ secrets.ORG_KEY }}
# SLACK_WEBHOOK_URL: '${{ secrets.SLACK_WEBHOOK_INJI_TEAM }}'
# SLACK_WEBHOOK_URL: '${{ secrets.SLACK_WEBHOOK_INJI_TEAM }}'

View File

@@ -200,7 +200,7 @@ fileignoreconfig:
- filename: screens/Home/IntroSlidersScreen.tsx
checksum: 9880724461b194db7651737576ad2fd2db9cf3b4e732747f59be422a7ff4e4a1
- filename: .env
checksum: ac76b852842c44ff5dac96c1fa5061e569bea4f54b3080d869a9dc25abd17991
checksum: f8375c44b0e70e691f942ea3323a0bf12cb0e2a7653a5551b34e2403a47119a8
- filename: machines/VCItemMachine/VCItemMachine.typegen.ts
checksum: 850b5d02636bef9e286fc0fbc4ffffbd38068f332c319302a906496f4bc1c8a1
- filename: machines/VerifiableCredential/VCItemMachine/VCItemModel.ts
@@ -258,7 +258,7 @@ fileignoreconfig:
- filename: machines/Issuers/IssuersMachine.ts
checksum: 1eb1e912ea76c88a8d477cce9742da59b5bb41a2a39cc1dc67c5bca240c1553b
- filename: .github/scripts/set-google-clientid.sh
checksum: 013ef3b43f50ba05e18c9c83e89cc366c3f0d8ed4d931ce7daa19a757880419b
checksum: 04de37335d2efb014107db49c751ba04e5993ffa868ea5a4e3bca57a64b00fe6
- filename: screens/Issuers/CredentialTypeSelectionScreen.tsx
checksum: 144bbf59e86a89bf580ac7931645ca3eaed69a9409de36f6ce9f88a14091a9d3
- filename: components/QrCodeOverlay.tsx
@@ -268,11 +268,11 @@ fileignoreconfig:
- filename: machines/Issuers/IssuersGuards.ts
checksum: 21783a057207ad04facdb4c71884f49b0230490def04158419d730e0cc60eb83
- filename: machines/Issuers/IssuersActions.ts
checksum: 4414aa10588d2305293b1902982c5969895c858355e4b91d01dfaa8601c2dd62
checksum: 7a7918df36cc41a9ebc5af763fe7c9e355be50223caf267315b12822000918cb
- filename: injitest/automation_trigger.sh
checksum: f2f34839c99cb1b871dde17aed8508a071345d22738796e005ff709d2dab8644
- filename: machines/Issuers/IssuersService.ts
checksum: e3832dff27687abc28609d2b281e570b4b0017995b7cfb56627a6b96949c469a
checksum: e33a75d4ea92db6e843900c9e57411f48bbe3d2fd43b78335f9cc6662cdfa85a
- filename: screens/Home/ViewVcModal.tsx
checksum: cfb25d562185488432b76287c4ef93359c1c64d8e29f5755d4c0a726c1485442
- filename: injitest/src/main/resources/TestData.json
@@ -310,7 +310,7 @@ fileignoreconfig:
- filename: machines/store.ts
checksum: 3fd2db0c41f8bd5f30ef922b856549cb5423997b2123c5364e643e47e5efd3cf
- filename: components/BannerNotificationContainer.tsx
checksum: 9e5b4a61b87e86666f0bee550d410df2b8576dfe5ec374de0ab139a468a234f7
checksum: 15bfe7b05ae7faa2a00f80a7efe35f7285b2178731908e80ac358cc5b3c740d0
- filename: injitest/src/test/java/iosTestCases/PinVcTest.java
checksum: 55098750062a199fdf1e33078acc50080dea12a885f934a7aa88411c06899cb7
- filename: injitest/src/test/java/androidTestCases/VcBackupAndRestoreTest.java
@@ -396,4 +396,6 @@ fileignoreconfig:
checksum: 9f29c9b0b91eba7fd7f5f4d1f78f9b6f96ef2c850c1346d712058a438d01036a
- filename: assets/InjiHomeLogo.svg
checksum: 6600a3d75033af4d702dd8c9663e12ad7c2c096a529bac2771bb856cc75a5ed0
- filename: locales/es.json
checksum: a03fae655b13342afb45ab2b79998f3e06afcb02346c2ddf6aaacacf3b027209
version: ""

View File

@@ -229,6 +229,12 @@ android {
dimension "inji"
resValue "string", "app_name", "Inji Wallet Mec"
}
reniec {
applicationId "io.mosip.inji.reniec"
versionName defaultConfig.versionName
dimension "inji"
resValue "string", "app_name", "Inji Wallet RENIEC"
}
}
android.applicationVariants.all { variant ->

View File

@@ -26,6 +26,8 @@ def generate_app_bundle_id()
return "io.mosip.inji.synergy"
when "mec"
return "io.mosip.inji.mec"
when "reniec"
return "io.mosip.inji.reniec"
end
end
@@ -42,6 +44,8 @@ def generate_app_name()
return "Inji Wallet Synergy"
when "mec"
return "Inji Wallet Mec"
when "reniec"
return "Inji Wallet RENIEC"
end
end

View File

@@ -23,6 +23,8 @@ export const BannerNotificationContainer: React.FC<
const bannerNotificationController = UseBannerNotification();
const WalletBindingSuccess = bannerNotificationController.isBindingSuccess;
const autoWalletBindingSuccess =
bannerNotificationController.isAutoWalletBindingSuccess;
const {t} = useTranslation('BannerNotification');
const rt = useTranslation('RequestScreen').t;
const verificationStatus = bannerNotificationController.verificationStatus;
@@ -55,19 +57,20 @@ export const BannerNotificationContainer: React.FC<
</View>
)}
{WalletBindingSuccess && (
<View style={Theme.BannerStyles.topBanner}>
<BannerNotification
type={BannerStatusType.SUCCESS}
message={t('activated')}
onClosePress={
bannerNotificationController.RESET_WALLET_BINDING_SUCCESS
}
key={'activatedVcPopup'}
testId={'activatedVcPopup'}
/>
</View>
)}
{WalletBindingSuccess ||
(!autoWalletBindingSuccess && (
<View style={Theme.BannerStyles.topBanner}>
<BannerNotification
type={BannerStatusType.SUCCESS}
message={t('activated')}
onClosePress={
bannerNotificationController.RESET_WALLET_BINDING_SUCCESS
}
key={'activatedVcPopup'}
testId={'activatedVcPopup'}
/>
</View>
))}
{showQuickShareSuccessBanner && (
<View style={Theme.BannerStyles.topBanner}>

View File

@@ -8,6 +8,7 @@ import {useContext} from 'react';
import {GlobalContext} from '../shared/GlobalContext';
import {VcMetaEvents} from '../machines/VerifiableCredential/VCMetaMachine/VCMetaMachine';
import {
selectAutoWalletBindingSuccess,
selectIsDownloadingFailed,
selectIsDownloadingSuccess,
selectWalletBindingSuccess,
@@ -21,11 +22,18 @@ export const UseBannerNotification = () => {
return {
isBindingSuccess: useSelector(vcMetaService, selectWalletBindingSuccess),
isAutoWalletBindingSuccess: useSelector(
vcMetaService,
selectAutoWalletBindingSuccess,
),
verificationStatus: useSelector(vcMetaService, selectVerificationStatus),
isPasscodeUnlock: useSelector(settingsService, selectIsPasscodeUnlock),
isBiometricUnlock: useSelector(settingsService, selectIsBiometricUnlock),
isDownloadingSuccess: useSelector(vcMetaService, selectIsDownloadingSuccess),
isDownloadingSuccess: useSelector(
vcMetaService,
selectIsDownloadingSuccess,
),
isDownloadingFailed: useSelector(vcMetaService, selectIsDownloadingFailed),
DISMISS: () => {
settingsService.send(SettingsEvents.DISMISS());

View File

@@ -189,21 +189,6 @@ export const HelpScreen: React.FC<HelpScreenProps> = props => {
<React.Fragment>{getTextField(t('answers.inji.eight'))}</React.Fragment>
),
},
{
title: t('questions.inji.nine'),
data: (
<React.Fragment>
{getTextField(
t('answers.inji.nine'),
getLinkedText(
injiHelpUrl +
'/functional-overview/end-user-guide#activating-a-vc',
t('here'),
),
)}
</React.Fragment>
),
},
{
title: t('questions.inji.ten'),
data: (
@@ -220,14 +205,6 @@ export const HelpScreen: React.FC<HelpScreenProps> = props => {
</React.Fragment>
),
},
{
title: t('questions.inji.eleven'),
data: (
<React.Fragment>
{getTextField(t('answers.inji.eleven'))}
</React.Fragment>
),
},
{
title: t('questions.inji.twelve'),
data: (

View File

@@ -18,6 +18,7 @@ import {RemoveVcWarningOverlay} from '../../../screens/Home/MyVcs/RemoveVcWarnin
import {HistoryTab} from '../../../screens/Home/MyVcs/HistoryTab';
import {useCopilot} from 'react-native-copilot';
import {useTranslation} from 'react-i18next';
import {addPngBase64Prefix} from '../../../shared/commonUtil';
export const VCCardViewContent: React.FC<VCItemContentProps> = props => {
const wellknownDisplayProperty = new Display(props.wellknown);
@@ -53,7 +54,7 @@ export const VCCardViewContent: React.FC<VCItemContentProps> = props => {
/>
));
const issuerLogo = props.verifiableCredentialData.issuerLogo;
const faceImage = props.verifiableCredentialData.face;
const faceImage = addPngBase64Prefix(props.verifiableCredentialData.face);
const {start} = useCopilot();
const {t} = useTranslation();

View File

@@ -21,9 +21,12 @@ import {
} from '../common/VCUtils';
import {ProfileIcon} from '../../ProfileIcon';
import {VCFormat} from '../../../shared/VCFormat';
import {VCItemField} from '../common/VCItemField';
import {addPngBase64Prefix} from '../../../shared/commonUtil';
const getProfileImage = (face: any) => {
if (face) {
face = addPngBase64Prefix(face);
return (
<Image source={{uri: face}} style={Theme.Styles.detailedViewImage} />
);

View File

@@ -4,9 +4,10 @@ import {Theme} from './ui/styleUtils';
import React from 'react';
import {ProfileIcon} from './ProfileIcon';
import {SvgImage} from './ui/svg';
import {addPngBase64Prefix} from '../shared/commonUtil';
export const VcItemContainerProfileImage = (props: VCItemContentProps) => {
const imageUri = props.verifiableCredentialData.face;
const imageUri = addPngBase64Prefix(props.verifiableCredentialData.face);
return imageUri ? (
<ImageBackground

18
i18n.ts
View File

@@ -2,29 +2,19 @@ import i18next from 'i18next';
import * as Localization from 'expo-localization';
import {initReactI18next} from 'react-i18next';
import en from './locales/en.json';
import fil from './locales/fil.json';
import ar from './locales/ara.json';
import hi from './locales/hin.json';
import kn from './locales/kan.json';
import ta from './locales/tam.json';
import es from './locales/es.json';
import {iso6393To1} from 'iso-639-3';
import {getItem} from './machines/store';
import {LocalizedField} from './machines/VerifiableCredential/VCMetaMachine/vc';
const resources = {en, fil, ar, hi, kn, ta};
const resources = {es};
const locale = Localization.locale;
const languageCodeMap = {} as {[key: string]: string};
export const SUPPORTED_LANGUAGES = {
en: 'English',
fil: 'Filipino',
ar: 'عربى',
hi: 'हिंदी',
kn: 'ಕನ್ನಡ',
ta: 'தமிழ்',
es: 'Española',
};
i18next
@@ -44,7 +34,7 @@ i18next
populateLanguageCodeMap();
}
if (!Object.keys(SUPPORTED_LANGUAGES).includes(i18next.language)) {
i18next.changeLanguage('en');
i18next.changeLanguage('es');
populateLanguageCodeMap();
}
});

View File

@@ -39,6 +39,8 @@ def generate_app_bundle_id()
return "io.mosip.inji.mobile.synergy"
when "mec"
return "io.mosip.inji.mec"
when "reniec"
return "io.mosip.inji.reniec"
end
end
@@ -55,6 +57,8 @@ def map_flavour_tosuffix()
return "mobile.synergy"
when "mec"
return "mec"
when "reniec"
return "reniec"
end
return flavor
end
@@ -72,6 +76,8 @@ def generate_app_name()
return "Inji Wallet Synergy"
when "mec"
return "Inji Wallet Mec"
when "reniec"
return "Inji Wallet RENIEC"
end
end

View File

@@ -241,6 +241,10 @@
"ERR_INVALID_VALIDFROM": "التاريخ غير صالح أو تم تحديده في المستقبل. تحقق من وجود تاريخ صالح.",
"ERR_VALID_FROM_IS_FUTURE_DATE": "التاريخ غير صالح أو تم تحديده في المستقبل. تحقق من وجود تاريخ صالح.",
"ERR_INVALID_VALIDUNTIL": "التاريخ غير صالح. تحقق من وجود تاريخ صالح."
},
"autoWalletBindingError": {
"title": "حدث خطأ!",
"message": "حدث خطأ ما أثناء معالجة بيانات الاعتماد الخاصة بك. يرجى محاولة تنزيلها مرة أخرى. إذا استمرت المشكلة، فتواصل مع الدعم للحصول على المساعدة."
}
}
},
@@ -257,9 +261,7 @@
"six": "ما هي بيانات الاعتماد التي يمكن التحقق منها؟",
"seven": "كيفية إضافة البطاقة؟",
"eight": "هل يمكنني إضافة بطاقات متعددة؟",
"nine": "لماذا يقول VC الخاص بي أن التنشيط معلق؟",
"ten": "ماذا تقصد بتفعيل تسجيل الدخول عبر الإنترنت؟",
"eleven": "كيفية تفعيل البطاقة لتسجيل الدخول عبر الإنترنت؟",
"twelve": "كيفية مشاركة البطاقة؟",
"thirteen": "كيفية إزالة البطاقة من المحفظة؟",
"fourteen": "كيفية عرض سجلات النشاط؟",
@@ -298,10 +300,8 @@
"six": "بيانات الاعتماد التي يمكن التحقق منها عبارة عن معلومات موقعة رقميًا تمثل بيانًا أدلى به المُصدر حول موضوع ما ويتضمن عادةً تفاصيل ديموغرافية. ",
"seven": "يمكن تنزيل المعرفات إلى INJI Mobile Wallet كبيانات اعتماد يمكن التحقق منها. ",
"eight": "نعم، يمكنك إضافة بطاقات متعددة إلى المحفظة من خلال الضغط على زر ''' في الصفحة الرئيسية.",
"nine": "بمجرد تنزيل عملة VC إلى محفظتك، فهي غير مرتبطة بعد بهوية المستخدم ولهذا السبب يقول VC الخاص بك أن التنشيط معلق. ",
"ten-a": "1. بمجرد ربط VC بالمحفظة بنجاح، يمكنك أن ترى أنه تم تنشيطه لتسجيل الدخول عبر الإنترنت مما يعني أنه يمكن الآن استخدام VC هذا في عملية تسجيل الدخول QR. ",
"ten-b": "2. س",
"eleven": "بعد إضافة البطاقة إلى المحفظة بنجاح، انقر فوق \"التنشيط معلق لتسجيل الدخول عبر الإنترنت\" الموجود على البطاقة. ",
"twelve": "انقر على زر \"مشاركة\" وقم بمسح رمز الاستجابة السريعة من الجهة الطالبة. ",
"thirteen-a": "يمكنك الضغط على...(قائمة كرات اللحم) الموجودة على البطاقة في الصفحة الرئيسية واختيار خيار إزالة من المحفظة لإزالة البطاقة من المحفظة. ",
"thirteen-b": " يرجى ملاحظة أنه يمكن تنزيل نفس البطاقة مرة أخرى.",

View File

@@ -258,9 +258,7 @@
"six": "What is a Verifiable Credential?",
"seven": "How to add a card?",
"eight": "Can I add multiple cards?",
"nine": "Why does my VC say Activation is pending?",
"ten": "What do you mean by Activated for Online login?",
"eleven": "How to activate a card for online login?",
"twelve": "How to share a card?",
"thirteen": "How to remove a card from the wallet?",
"fourteen": "How to view activity logs?",
@@ -299,10 +297,8 @@
"six": "A Verifiable Credential is a digitally signed piece of information that represents a statement made by the issuer about a subject and typically includes demographic details. VCs are secure and trustworthy in various online interactions.",
"seven": "IDs can be downloaded to INJI Mobile Wallet as Verifiable Credentials. To know how to download VCs with various IDs please read",
"eight": "Yes, you can add multiple cards to the wallet by clicking on '+' button on the Home page.",
"nine": "Once VC is downloaded to your wallet, it is not yet bound with the users identity which is why your VC says Activation Pending. Binding your VC to your wallet (with your passcode or biometrics) is crucial to ensure the highest level of security. To activate your VC, please follow the steps",
"ten-a": "1. Once the VC is successfully binded with the wallet, you can see that it is Activated for Online login which means this VC can now be used for the QR login process. To know more about QR code login, please read",
"ten-b": "2. The Q&A should be readable and understandable even when the user changes the language in the INJI app.",
"eleven": "After successfully adding a card to the wallet, click on 'Activation pending for Online login' on the card. On clicking on 'Activate', the card will be ready to be used for online login.",
"twelve": "Click on 'Share' button and scan the QR code from the requesting party. Once the connection is established, the card will be shared.",
"thirteen-a": "You can click on ...(meatballs menu) on a card in the Home page and choose Remove from Wallet option to remove a card from the wallet. To know more, please read",
"thirteen-b": " Please note that, the same card can be downloaded again.",
@@ -459,6 +455,10 @@
"ERR_INVALID_VALIDFROM": "Date is invalid or set in the future. Check for a valid date.",
"ERR_VALID_FROM_IS_FUTURE_DATE": "Date is invalid or set in the future. Check for a valid date.",
"ERR_INVALID_VALIDUNTIL": "Date is invalid. Check for a valid date."
},
"autoWalletBindingError": {
"title": "An Error Occurred!",
"message": "Something went wrong while processing your credential. Please try downloading it again. If the issue persists, reach out to support for help."
}
}
},

1053
locales/es.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -257,9 +257,7 @@
"six": "Ano ang isang Nabe-verify na Kredensyal?",
"seven": "Paano magdagdag ng card?",
"eight": "Maaari ba akong magdagdag ng maraming card?",
"nine": "Bakit sinasabi ng aking VC na nakabinbin ang Activation?",
"ten": "Ano ang ibig mong sabihin sa Activated for Online login?",
"eleven": "Paano i-activate ang isang card para sa online na pag-login?",
"twelve": "Paano magbahagi ng card?",
"thirteen": "Paano mag-alis ng card mula sa wallet?",
"fourteen": "Paano tingnan ang mga log ng aktibidad?",
@@ -298,10 +296,8 @@
"six": "Ang Nabe-verify na Kredensyal ay isang digitally signed na piraso ng impormasyon na kumakatawan sa isang pahayag na ginawa ng issuer tungkol sa isang paksa at karaniwang may kasamang mga detalye ng demograpiko. ",
"seven": "Maaaring ma-download ang mga ID sa INJI Mobile Wallet bilang Mga Nabe-verify na Kredensyal. ",
"eight": "Oo, maaari kang magdagdag ng maramihang mga card sa wallet sa pamamagitan ng pag-click sa pindutang ' ' sa Home page.",
"nine": "Kapag na-download na ang VC sa iyong wallet, hindi pa ito nakatali sa pagkakakilanlan ng user kung kaya't sinasabi ng iyong VC na Nakabinbin ang Aktibidad. ",
"ten-a": "1. Kapag matagumpay na na-binded ang VC sa wallet, makikita mo na ito ay Activated for Online login which means itong VC ay magagamit na para sa QR login process. ",
"ten-b": "2. Ang Q",
"eleven": "Pagkatapos matagumpay na magdagdag ng card sa wallet, mag-click sa 'Activation pending for Online login' sa card. ",
"twelve": "Mag-click sa pindutang 'Ibahagi' at i-scan ang QR code mula sa humihiling na partido. ",
"thirteen-a": "Maaari kang mag-click sa ...(meatballs menu) sa isang card sa Home page at piliin ang Remove from Wallet na opsyon upang alisin ang isang card mula sa wallet. ",
"thirteen-b": " Pakitandaan na, maaaring i-download muli ang parehong card.",
@@ -458,6 +454,10 @@
"ERR_INVALID_VALIDFROM": "Ang petsa ay hindi wasto o nakatakda sa hinaharap. Tingnan kung may wastong petsa.",
"ERR_VALID_FROM_IS_FUTURE_DATE": "Ang petsa ay hindi wasto o nakatakda sa hinaharap. Tingnan kung may wastong petsa.",
"ERR_INVALID_VALIDUNTIL": "Di-wasto ang petsa. Tingnan kung may wastong petsa."
},
"autoWalletBindingError": {
"title": "May pagkakamaling naganap!",
"message": "Nagkaproblema habang pinoproseso ang iyong kredensyal. Pakisubukang i-download itong muli. Kung magpapatuloy ang isyu, makipag-ugnayan sa suporta para sa tulong."
}
}
},

View File

@@ -242,6 +242,10 @@
"ERR_INVALID_VALIDFROM": "दिनांक अमान्य है या भविष्य में सेट है. वैध तिथि की जांच करें.",
"ERR_VALID_FROM_IS_FUTURE_DATE": "दिनांक अमान्य है या भविष्य में सेट है. वैध तिथि की जांच करें.",
"ERR_INVALID_VALIDUNTIL": "दिनांक अमान्य है. वैध तिथि की जांच करें."
},
"autoWalletBindingError": {
"title": "एक त्रुटि पाई गई!",
"message": "आपके क्रेडेंशियल को प्रोसेस करते समय कुछ गड़बड़ हो गई। कृपया इसे फिर से डाउनलोड करने का प्रयास करें। अगर समस्या बनी रहती है, तो सहायता के लिए सहायता केंद्र से संपर्क करें।"
}
}
},
@@ -258,9 +262,7 @@
"six": "सत्यापन योग्य क्रेडेंशियल क्या है?",
"seven": "कार्ड कैसे जोड़ें?",
"eight": "क्या मैं एकाधिक कार्ड जोड़ सकता हूँ?",
"nine": "मेरा वीसी यह क्यों कहता है कि सक्रियण लंबित है?",
"ten": "ऑनलाइन लॉगिन के लिए सक्रिय से आपका क्या तात्पर्य है?",
"eleven": "ऑनलाइन लॉगिन के लिए कार्ड कैसे सक्रिय करें?",
"twelve": "कार्ड कैसे साझा करें?",
"thirteen": "वॉलेट से कार्ड कैसे निकालें?",
"fourteen": "गतिविधि लॉग कैसे देखें?",
@@ -299,10 +301,8 @@
"six": "सत्यापन योग्य क्रेडेंशियल डिजिटल रूप से हस्ताक्षरित जानकारी का एक टुकड़ा है जो किसी विषय के बारे में जारीकर्ता द्वारा दिए गए बयान का प्रतिनिधित्व करता है और इसमें आम तौर पर जनसांख्यिकीय विवरण शामिल होते हैं। ",
"seven": "आईडी को INJI मोबाइल वॉलेट में सत्यापन योग्य क्रेडेंशियल के रूप में डाउनलोड किया जा सकता है। ",
"eight": "हां, आप होम पेज पर '' बटन पर क्लिक करके वॉलेट में कई कार्ड जोड़ सकते हैं।",
"nine": "एक बार वीसी आपके वॉलेट में डाउनलोड हो जाने के बाद, यह अभी तक उपयोगकर्ता की पहचान से बंधा नहीं है, यही कारण है कि आपका वीसी सक्रियण लंबित कहता है। ",
"ten-a": "1. एक बार जब वीसी सफलतापूर्वक वॉलेट से जुड़ जाता है, तो आप देख सकते हैं कि यह ऑनलाइन लॉगिन के लिए सक्रिय है, जिसका अर्थ है कि इस वीसी का उपयोग अब क्यूआर लॉगिन प्रक्रिया के लिए किया जा सकता है। ",
"ten-b": "2. प्र",
"eleven": "वॉलेट में सफलतापूर्वक कार्ड जोड़ने के बाद, कार्ड पर 'ऑनलाइन लॉगिन के लिए सक्रियण लंबित' पर क्लिक करें। ",
"twelve": "'शेयर' बटन पर क्लिक करें और अनुरोध करने वाले पक्ष से क्यूआर कोड स्कैन करें। ",
"thirteen-a": "आप होम पेज में कार्ड पर ...(मीटबॉल मेनू) पर क्लिक कर सकते हैं और वॉलेट से कार्ड हटाने के लिए वॉलेट से निकालें विकल्प चुन सकते हैं। ",
"thirteen-b": " कृपया ध्यान दें कि, उसी कार्ड को दोबारा डाउनलोड किया जा सकता है।",

View File

@@ -241,6 +241,10 @@
"ERR_INVALID_VALIDFROM": "ದಿನಾಂಕ ಅಮಾನ್ಯವಾಗಿದೆ ಅಥವಾ ಭವಿಷ್ಯದಲ್ಲಿ ಹೊಂದಿಸಲಾಗಿದೆ. ಮಾನ್ಯವಾದ ದಿನಾಂಕವನ್ನು ಪರಿಶೀಲಿಸಿ.",
"ERR_VALID_FROM_IS_FUTURE_DATE": "ದಿನಾಂಕ ಅಮಾನ್ಯವಾಗಿದೆ ಅಥವಾ ಭವಿಷ್ಯದಲ್ಲಿ ಹೊಂದಿಸಲಾಗಿದೆ. ಮಾನ್ಯವಾದ ದಿನಾಂಕವನ್ನು ಪರಿಶೀಲಿಸಿ.",
"ERR_INVALID_VALIDUNTIL": "ದಿನಾಂಕ ಅಮಾನ್ಯವಾಗಿದೆ. ಮಾನ್ಯವಾದ ದಿನಾಂಕವನ್ನು ಪರಿಶೀಲಿಸಿ."
},
"autoWalletBindingError": {
"title": "ಒಂದು ತಪ್ಪು ನಡೆದಿದೆ!",
"message": "ನಿಮ್ಮ ರುಜುವಾತುಗಳನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುವಾಗ ಏನೋ ತಪ್ಪಾಗಿದೆ. ದಯವಿಟ್ಟು ಅದನ್ನು ಮತ್ತೊಮ್ಮೆ ಡೌನ್\u200Cಲೋಡ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿ. ಸಮಸ್ಯೆ ಮುಂದುವರಿದರೆ, ಸಹಾಯಕ್ಕಾಗಿ ಬೆಂಬಲವನ್ನು ಸಂಪರ್ಕಿಸಿ."
}
}
},
@@ -257,9 +261,7 @@
"six": "ಪರಿಶೀಲಿಸಬಹುದಾದ ರುಜುವಾತು ಎಂದರೇನು?",
"seven": "ಕಾರ್ಡ್ ಅನ್ನು ಹೇಗೆ ಸೇರಿಸುವುದು?",
"eight": "ನಾನು ಬಹು ಕಾರ್ಡ್‌ಗಳನ್ನು ಸೇರಿಸಬಹುದೇ?",
"nine": "ಸಕ್ರಿಯಗೊಳಿಸುವಿಕೆ ಬಾಕಿಯಿದೆ ಎಂದು ನನ್ನ VC ಏಕೆ ಹೇಳುತ್ತಾರೆ?",
"ten": "ಆನ್‌ಲೈನ್ ಲಾಗಿನ್‌ಗಾಗಿ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ ಎಂಬುದರ ಅರ್ಥವೇನು?",
"eleven": "ಆನ್‌ಲೈನ್ ಲಾಗಿನ್‌ಗಾಗಿ ಕಾರ್ಡ್ ಅನ್ನು ಹೇಗೆ ಸಕ್ರಿಯಗೊಳಿಸುವುದು?",
"twelve": "ಕಾರ್ಡ್ ಹಂಚಿಕೊಳ್ಳುವುದು ಹೇಗೆ?",
"thirteen": "ವ್ಯಾಲೆಟ್ನಿಂದ ಕಾರ್ಡ್ ಅನ್ನು ಹೇಗೆ ತೆಗೆದುಹಾಕುವುದು?",
"fourteen": "ಚಟುವಟಿಕೆ ಲಾಗ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸುವುದು ಹೇಗೆ?",
@@ -298,10 +300,8 @@
"six": "ಪರಿಶೀಲಿಸಬಹುದಾದ ರುಜುವಾತು ಎನ್ನುವುದು ಡಿಜಿಟಲ್ ಸಹಿ ಮಾಡಿದ ಮಾಹಿತಿಯ ತುಣುಕು, ಇದು ವಿಷಯದ ಬಗ್ಗೆ ನೀಡುವವರು ಮಾಡಿದ ಹೇಳಿಕೆಯನ್ನು ಪ್ರತಿನಿಧಿಸುತ್ತದೆ ಮತ್ತು ಸಾಮಾನ್ಯವಾಗಿ ಜನಸಂಖ್ಯಾ ವಿವರಗಳನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ. ",
"seven": "ಐಡಿಗಳನ್ನು ಪರಿಶೀಲಿಸಬಹುದಾದ ರುಜುವಾತುಗಳಂತೆ INJI ಮೊಬೈಲ್ ವಾಲೆಟ್‌ಗೆ ಡೌನ್‌ಲೋಡ್ ಮಾಡಬಹುದು. ",
"eight": "ಹೌದು, ಮುಖಪುಟದಲ್ಲಿ ' ' ಬಟನ್ ಕ್ಲಿಕ್ ಮಾಡುವ ಮೂಲಕ ನೀವು ಬಹು ಕಾರ್ಡ್‌ಗಳನ್ನು ವ್ಯಾಲೆಟ್‌ಗೆ ಸೇರಿಸಬಹುದು.",
"nine": "ಒಮ್ಮೆ VC ಅನ್ನು ನಿಮ್ಮ ವ್ಯಾಲೆಟ್‌ಗೆ ಡೌನ್‌ಲೋಡ್ ಮಾಡಿದರೆ, ಅದು ಇನ್ನೂ ಬಳಕೆದಾರರ ಗುರುತಿನೊಂದಿಗೆ ಬದ್ಧವಾಗಿಲ್ಲ, ಅದಕ್ಕಾಗಿಯೇ ನಿಮ್ಮ VC ಸಕ್ರಿಯಗೊಳಿಸುವಿಕೆ ಬಾಕಿಯಿದೆ ಎಂದು ಹೇಳುತ್ತದೆ. ",
"ten-a": "1. VC ಅನ್ನು ವ್ಯಾಲೆಟ್‌ನೊಂದಿಗೆ ಯಶಸ್ವಿಯಾಗಿ ಬಂಧಿಸಿದ ನಂತರ, ಅದನ್ನು ಆನ್‌ಲೈನ್ ಲಾಗಿನ್‌ಗಾಗಿ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ ಎಂದು ನೀವು ನೋಡಬಹುದು ಅಂದರೆ ಈ VC ಅನ್ನು ಈಗ QR ಲಾಗಿನ್ ಪ್ರಕ್ರಿಯೆಗೆ ಬಳಸಬಹುದು. ",
"ten-b": "2. ಪ್ರಶ್ನೆ",
"eleven": "ವ್ಯಾಲೆಟ್‌ಗೆ ಕಾರ್ಡ್ ಅನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಸೇರಿಸಿದ ನಂತರ, ಕಾರ್ಡ್‌ನಲ್ಲಿರುವ 'ಆನ್‌ಲೈನ್ ಲಾಗಿನ್‌ಗಾಗಿ ಆಕ್ಟಿವೇಶನ್ ಪೆಂಡಿಂಗ್' ಅನ್ನು ಕ್ಲಿಕ್ ಮಾಡಿ. ",
"twelve": "'ಹಂಚಿಕೊಳ್ಳಿ' ಬಟನ್ ಕ್ಲಿಕ್ ಮಾಡಿ ಮತ್ತು ವಿನಂತಿಸಿದ ಪಕ್ಷದಿಂದ QR ಕೋಡ್ ಅನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಿ. ",
"thirteen-a": "ನೀವು ಮುಖಪುಟದಲ್ಲಿ ಕಾರ್ಡ್‌ನಲ್ಲಿ ...(ಮೀಟ್‌ಬಾಲ್ಸ್ ಮೆನು) ಅನ್ನು ಕ್ಲಿಕ್ ಮಾಡಬಹುದು ಮತ್ತು ವ್ಯಾಲೆಟ್‌ನಿಂದ ಕಾರ್ಡ್ ಅನ್ನು ತೆಗೆದುಹಾಕಲು ವಾಲೆಟ್‌ನಿಂದ ತೆಗೆದುಹಾಕಿ ಆಯ್ಕೆಯನ್ನು ಆರಿಸಿ. ",
"thirteen-b": " ಅದೇ ಕಾರ್ಡ್ ಅನ್ನು ಮತ್ತೆ ಡೌನ್‌ಲೋಡ್ ಮಾಡಬಹುದು ಎಂಬುದನ್ನು ದಯವಿಟ್ಟು ಗಮನಿಸಿ.",

View File

@@ -241,6 +241,10 @@
"ERR_INVALID_VALIDFROM": "தேதி தவறானது அல்லது எதிர்காலத்தில் அமைக்கப்படும். சரியான தேதியைச் சரிபார்க்கவும்.",
"ERR_VALID_FROM_IS_FUTURE_DATE": "தேதி தவறானது அல்லது எதிர்காலத்தில் அமைக்கப்படும். சரியான தேதியைச் சரிபார்க்கவும்.",
"ERR_INVALID_VALIDUNTIL": "தேதி தவறானது. சரியான தேதியைச் சரிபார்க்கவும்."
},
"autoWalletBindingError": {
"title": "ஒரு பிழை ஏற்பட்டது!",
"message": "உங்கள் நற்சான்றிதழைச் செயலாக்கும்போது ஏதோ தவறு ஏற்பட்டது. தயவு செய்து மீண்டும் பதிவிறக்க முயற்சிக்கவும். சிக்கல் தொடர்ந்தால், உதவிக்கு ஆதரவை அணுகவும்."
}
}
},
@@ -257,9 +261,7 @@
"six": "சரிபார்க்கக்கூடிய நற்சான்றிதழ் என்றால் என்ன?",
"seven": "அட்டையை எவ்வாறு சேர்ப்பது?",
"eight": "நான் பல அட்டைகளைச் சேர்க்கலாமா?",
"nine": "செயல்படுத்தல் நிலுவையில் இருப்பதாக எனது VC ஏன் கூறுகிறார்?",
"ten": "ஆன்லைன் உள்நுழைவுக்காக செயல்படுத்தப்பட்டது என்பதன் அர்த்தம் என்ன?",
"eleven": "ஆன்லைன் உள்நுழைவுக்கான அட்டையை எவ்வாறு செயல்படுத்துவது?",
"twelve": "ஒரு அட்டையை எவ்வாறு பகிர்வது?",
"thirteen": "பணப்பையில் இருந்து அட்டையை எவ்வாறு அகற்றுவது?",
"fourteen": "செயல்பாட்டுப் பதிவுகளை எவ்வாறு பார்ப்பது?",
@@ -298,10 +300,8 @@
"six": "சரிபார்க்கக்கூடிய நற்சான்றிதழ் என்பது டிஜிட்டல் கையொப்பமிடப்பட்ட தகவலாகும், இது ஒரு விஷயத்தைப் பற்றி வழங்குபவரின் அறிக்கையைப் பிரதிபலிக்கிறது மற்றும் பொதுவாக மக்கள்தொகை விவரங்களை உள்ளடக்கியது. ",
"seven": "ஐடிகளை சரிபார்க்கக்கூடிய சான்றுகளாக INJI மொபைல் வாலட்டில் பதிவிறக்கம் செய்யலாம். ",
"eight": "ஆம், முகப்புப் பக்கத்தில் உள்ள ' ' பொத்தானைக் கிளிக் செய்வதன் மூலம் பணப்பையில் பல கார்டுகளைச் சேர்க்கலாம்.",
"nine": "உங்கள் வாலட்டில் VC பதிவிறக்கம் செய்யப்பட்டவுடன், அது இன்னும் பயனரின் அடையாளத்துடன் பிணைக்கப்படவில்லை, அதனால்தான் உங்கள் VC செயல்படுத்தல் நிலுவையில் உள்ளது எனக் கூறுகிறது. ",
"ten-a": "1. VC வெற்றிகரமாக வாலட்டுடன் பிணைக்கப்பட்டவுடன், அது ஆன்லைன் உள்நுழைவுக்காக செயல்படுத்தப்பட்டிருப்பதைக் காணலாம், அதாவது இந்த VC இப்போது QR உள்நுழைவு செயல்முறைக்கு பயன்படுத்தப்படலாம். ",
"ten-b": "2. கே",
"eleven": "வாலட்டில் கார்டை வெற்றிகரமாகச் சேர்த்த பிறகு, கார்டில் உள்ள 'ஆன்லைன் உள்நுழைவுக்கான ஆக்டிவேஷன் பெண்டிங்' என்பதைக் கிளிக் செய்யவும். ",
"twelve": "'பகிர்' பொத்தானைக் கிளிக் செய்து, கோரும் தரப்பினரிடமிருந்து QR குறியீட்டை ஸ்கேன் செய்யவும். ",
"thirteen-a": "முகப்புப் பக்கத்தில் உள்ள கார்டில் ...(மீட்பால்ஸ் மெனு) என்பதைக் கிளிக் செய்து, பணப்பையிலிருந்து அட்டையை அகற்ற, வாலட்டில் இருந்து அகற்று விருப்பத்தைத் தேர்வுசெய்யலாம். ",
"thirteen-b": " அதே அட்டையை மீண்டும் பதிவிறக்கம் செய்யலாம் என்பதை நினைவில் கொள்ளவும்.",

View File

@@ -9,6 +9,7 @@ import {
REQUEST_TIMEOUT,
isIOS,
EXPIRED_VC_ERROR_CODE,
DEFAULT_OTP,
} from '../../shared/constants';
import {assign, send} from 'xstate';
import {StoreEvents} from '../store';
@@ -20,6 +21,8 @@ import {
getEndEventData,
getImpressionEventData,
sendEndEvent,
getStartEventData,
sendStartEvent,
sendImpressionEvent,
} from '../../shared/telemetry/TelemetryUtils';
import {TelemetryConstants} from '../../shared/telemetry/TelemetryConstants';
@@ -27,6 +30,8 @@ import {NativeModules} from 'react-native';
import {KeyTypes} from '../../shared/cryptoutil/KeyTypes';
import {VCActivityLog} from '../../components/ActivityLogEvent';
import {isNetworkError} from '../../shared/Utils';
import {WalletBindingResponse} from '../VerifiableCredential/VCMetaMachine/vc';
import {getBindingCertificateConstant} from '../../shared/keystore/SecureKeystore';
const {RNSecureKeystoreModule} = NativeModules;
export const IssuersActions = (model: any) => {
@@ -347,6 +352,14 @@ export const IssuersActions = (model: any) => {
verificationErrorMessage: () => '',
}),
setAutoWalletBindingFailure: assign({
isAutoWalletBindingFailed: () => true,
}),
resetAutoWalletBindingFailure: model.assign({
isAutoWalletBindingFailed: () => false,
}),
sendDownloadingFailedToVcMeta: send(
(_: any) => ({
type: 'VC_DOWNLOADING_FAILED',
@@ -355,5 +368,64 @@ export const IssuersActions = (model: any) => {
to: context => context.serviceRefs.vcMeta,
},
),
unsetOTP: model.assign({OTP: () => ''}),
setOTP: model.assign({
OTP: (_, event) => {
return DEFAULT_OTP;
},
}),
setWalletBindingResponse: (context: any, event: any) => {
context.credentialWrapper = {
...context.credentialWrapper,
walletBindingResponse: event.data as WalletBindingResponse,
};
},
sendActivationStartEvent: context => {
sendStartEvent(
getStartEventData(
context.isMachineInKebabPopupState
? TelemetryConstants.FlowType.vcActivationFromKebab
: TelemetryConstants.FlowType.vcActivation,
),
);
},
setThumbprintForWalletBindingId: send(
(context: any) => {
const {credentialWrapper} = context;
const walletBindingIdKey = getBindingCertificateConstant(
credentialWrapper.walletBindingResponse.walletBindingId,
);
return StoreEvents.SET(
walletBindingIdKey,
credentialWrapper.walletBindingResponse.thumbprint,
);
},
{
to: context => context.serviceRefs.store,
},
),
resetPrivateKey: assign({
privateKey: () => '',
}),
sendActivationSuccessEvent: context =>
sendEndEvent(
getEndEventData(
context.isMachineInKebabPopupState
? TelemetryConstants.FlowType.vcActivationFromKebab
: TelemetryConstants.FlowType.vcActivation,
TelemetryConstants.EndEventStatus.success,
{'Activation key': context.vcMetadata?.downloadKeyType},
),
),
sendWalletBindingSuccess: send(
context => {
return {
type: 'AUTO_WALLET_BINDING_SUCCESS',
};
},
{
to: (context: any) => context.serviceRefs.vcMeta,
},
),
};
};

View File

@@ -11,6 +11,7 @@ export const IssuersEvents = {
CANCEL: () => ({}),
STORE_RESPONSE: (response?: unknown) => ({response}),
STORE_ERROR: (error: Error, requester?: string) => ({error, requester}),
RESET_VERIFY_ERROR: () => ({}),
RESET_ERROR_SCREEN: () => ({}),
SELECTED_CREDENTIAL_TYPE: (credType: CredentialTypes) => ({credType}),
SHOW_BINDING_STATUS: () => ({}),
};

View File

@@ -3,6 +3,7 @@ import {ErrorMessage, OIDCErrors} from '../../shared/openId4VCI/Utils';
import {isHardwareKeystoreExists} from '../../shared/cryptoutil/cryptoUtil';
import {BiometricCancellationError} from '../../shared/error/BiometricCancellationError';
import {VerificationErrorType} from '../../shared/vcjs/verifyCredential';
import {DEFAULT_OTP} from '../../shared/constants';
export const IssuersGuards = () => {
return {
@@ -57,5 +58,7 @@ export const IssuersGuards = () => {
const errorMessage = event.data.message;
return errorMessage === ErrorMessage.GENERIC;
},
isAutoWalletBindingFlow: (context: any, event: any) =>
context?.OTP === DEFAULT_OTP,
};
};

View File

@@ -358,6 +358,16 @@ export const IssuersMachine = model.createMachine(
cond: 'isCustomSecureKeystore',
target: 'downloadCredentials',
},
{
cond: 'isAutoWalletBindingFlow',
actions: [
'setPublicKey',
'setPrivateKey',
'setLoadingReasonAsDownloadingCredentials',
'storeKeyPair',
],
target: 'addingWalletBindingId',
},
{
actions: [
// to be decided
@@ -369,6 +379,13 @@ export const IssuersMachine = model.createMachine(
target: 'downloadCredentials',
},
],
onError: [
{
cond: 'isAutoWalletBindingFlow',
actions: 'setAutoWalletBindingFailure',
target: 'handleVCAutoWalletBindingFailure',
},
],
},
},
downloadCredentials: {
@@ -432,8 +449,12 @@ export const IssuersMachine = model.createMachine(
src: 'verifyCredential',
onDone: [
{
actions: ['sendSuccessEndEvent', 'setVerificationResult'],
target: 'storing',
actions: [
'sendSuccessEndEvent',
'setVerificationResult',
'setVCMetadata',
],
target: 'requestingBindingOTP',
},
],
onError: [
@@ -454,14 +475,94 @@ export const IssuersMachine = model.createMachine(
},
},
requestingBindingOTP: {
entry: 'sendActivationStartEvent',
invoke: {
src: 'requestBindingOTP',
onDone: [
{
target: 'addKeyPair',
actions: ['unsetOTP', 'setOTP'],
},
],
onError: [
{
actions: 'setAutoWalletBindingFailure',
target: 'handleVCAutoWalletBindingFailure',
},
],
},
},
addKeyPair: {
invoke: {
src: 'fetchKeyPair',
onDone: [
{
cond: 'hasKeyPair',
actions: ['setPublicKey'],
target: 'addingWalletBindingId',
},
{
target: 'generateKeyPair',
},
],
onError: [
{
actions: 'setAutoWalletBindingFailure',
target: 'handleVCAutoWalletBindingFailure',
},
],
},
},
addingWalletBindingId: {
invoke: {
src: 'addWalletBindingId',
onDone: [
{
cond: 'isCustomSecureKeystore',
actions: ['setWalletBindingResponse'],
target: 'updatingContextVariables',
},
],
onError: [
{
actions: 'setAutoWalletBindingFailure',
target: 'handleVCAutoWalletBindingFailure',
},
],
},
},
updatingContextVariables: {
entry: [
'setThumbprintForWalletBindingId',
'resetPrivateKey',
send('SHOW_BINDING_STATUS'),
],
on: {
SHOW_BINDING_STATUS: [
{
actions: 'sendWalletBindingSuccess',
target: 'storing',
},
],
},
},
handleVCVerificationFailure: {
on: {
RESET_VERIFY_ERROR: {
RESET_ERROR_SCREEN: {
actions: ['resetVerificationErrorMessage'],
},
},
},
handleVCAutoWalletBindingFailure: {
on: {
RESET_ERROR_SCREEN: {
actions: ['resetAutoWalletBindingFailure'],
},
},
},
storing: {
description: 'all the verified credential is stored.',
entry: [

View File

@@ -10,6 +10,7 @@ import {AppServices} from '../../shared/GlobalContext';
import {VCMetadata} from '../../shared/VCMetadata';
import {IssuersEvents} from './IssuersEvents';
import {issuerType} from './IssuersMachine';
import {CommunicationDetails} from '../../shared/Utils';
export const IssuersModel = createModel(
{
@@ -31,6 +32,8 @@ export const IssuersModel = createModel(
vcMetadata: {} as VCMetadata,
keyType: 'RS256' as string,
wellknownKeyTypes: [] as string[],
OTP: '',
isAutoWalletBindingFailed: false,
},
{
events: IssuersEvents,

View File

@@ -58,6 +58,10 @@ export function selectVerificationErrorMessage(state: State) {
return state.context.verificationErrorMessage;
}
export function selectAutoWalletBindingFailure(state: State) {
return state.context.isAutoWalletBindingFailed;
}
export function selectSelectingCredentialType(state: State) {
return state.matches('selectingCredentialType');
}

View File

@@ -1,5 +1,5 @@
import Cloud from '../../shared/CloudBackupAndRestoreUtils';
import {CACHED_API} from '../../shared/api';
import {API_URLS, CACHED_API} from '../../shared/api';
import NetInfo from '@react-native-community/netinfo';
import {
constructAuthorizationConfiguration,
@@ -29,6 +29,8 @@ import {TelemetryConstants} from '../../shared/telemetry/TelemetryConstants';
import {VciClient} from '../../shared/vciClient/VciClient';
import {isMockVC} from '../../shared/Utils';
import {VCFormat} from '../../shared/VCFormat';
import {request} from '../../shared/request';
import {WalletBindingResponse} from '../VerifiableCredential/VCMetaMachine/vc';
export const IssuersService = () => {
return {
@@ -172,5 +174,62 @@ export const IssuersService = () => {
};
}
},
requestBindingOTP: async (context: any) => {
const response = await request(
API_URLS.bindingOtp.method,
API_URLS.bindingOtp.buildURL(),
{
requestTime: String(new Date().toISOString()),
request: {
individualId:
context.verifiableCredential.credential.credentialSubject.dni,
otpChannels: ['EMAIL', 'PHONE'],
},
},
);
if (response.response == null) {
throw new Error('Could not process request');
}
return response;
},
fetchKeyPair: async context => {
const keyType = context.vcMetadata?.downloadKeyType;
return await fetchKeyPair(keyType);
},
addWalletBindingId: async context => {
const response = await request(
API_URLS.walletBinding.method,
API_URLS.walletBinding.buildURL(),
{
requestTime: String(new Date().toISOString()),
request: {
authFactorType: 'WLA',
format: 'jwt',
individualId:
context.verifiableCredential.credential.credentialSubject.dni,
transactionId: context.bindingTransactionId,
publicKey: context.publicKey,
challengeList: [
{
authFactorType: 'OTP',
challenge: context.OTP,
format: 'alpha-numeric',
},
],
},
},
);
const walletResponse: WalletBindingResponse = {
walletBindingId: response.response.encryptedWalletBindingId,
keyId: response.response.keyId,
thumbprint: response.response.thumbprint,
expireDateTime: response.response.expireDateTime,
};
return walletResponse;
},
};
};

View File

@@ -218,6 +218,12 @@ export const VCMetaActions = (model: any) => {
...getUpdatedVCMetadatas(context.myVcsMetadata, event.vcMetadata),
],
}),
setAutoWalletBindingSuccess: model.assign({
autoWalletBindingSuccess: true,
}),
resetAutoWalletBindingSuccess: model.assign({
autoWalletBindingSuccess: false,
}),
setWalletBindingSuccess: model.assign({
walletBindingSuccess: true,

View File

@@ -18,6 +18,7 @@ export const VcMetaEvents = {
REFRESH_MY_VCS_TWO: (vc: VC) => ({vc}),
REFRESH_RECEIVED_VCS: () => ({}),
WALLET_BINDING_SUCCESS: () => ({}),
AUTO_WALLET_BINDING_SUCCESS: () => ({}),
RESET_WALLET_BINDING_SUCCESS: () => ({}),
ADD_VC_TO_IN_PROGRESS_DOWNLOADS: (requestId: string) => ({requestId}),
REMOVE_VC_FROM_IN_PROGRESS_DOWNLOADS: (vcMetadata: VCMetadata) => ({
@@ -31,7 +32,7 @@ export const VcMetaEvents = {
errorMessage,
vcMetadata,
}),
RESET_VERIFY_ERROR: () => ({}),
RESET_ERROR_SCREEN: () => ({}),
REFRESH_VCS_METADATA: () => ({}),
SHOW_TAMPERED_POPUP: () => ({}),
SET_VERIFICATION_STATUS: (verificationStatus: unknown) => ({

View File

@@ -25,8 +25,8 @@ export const vcMetaMachine =
VC_DOWNLOADING_FAILED: {
actions: 'setDownloadCreadentialsFailed',
},
RESET_DOWNLOADING_SUCCESS:{
actions: 'resetDownloadCredentialsSuccess'
RESET_DOWNLOADING_SUCCESS: {
actions: 'resetDownloadCredentialsSuccess',
},
RESET_DOWNLOADING_FAILED: {
actions: 'resetDownloadCreadentialsFailed',
@@ -105,6 +105,9 @@ export const vcMetaMachine =
WALLET_BINDING_SUCCESS: {
actions: 'setWalletBindingSuccess',
},
AUTO_WALLET_BINDING_SUCCESS: {
actions: 'setAutoWalletBindingSuccess',
},
GET_VC_ITEM: {
actions: 'getVcItemResponse',
},
@@ -118,7 +121,7 @@ export const vcMetaMachine =
actions: ['updateMyVcsMetadata', 'setUpdatedVcMetadatas'],
},
VC_DOWNLOADED: {
actions: ['setDownloadCredentialsSuccess','setDownloadedVc',]
actions: ['setDownloadCredentialsSuccess', 'setDownloadedVc'],
},
ADD_VC_TO_IN_PROGRESS_DOWNLOADS: {
actions: 'addVcToInProgressDownloads',
@@ -151,7 +154,7 @@ export const vcMetaMachine =
],
target: '#vcMeta.ready',
},
RESET_VERIFY_ERROR: {
RESET_ERROR_SCREEN: {
actions: 'resetVerificationErrorMessage',
},
SET_VERIFICATION_STATUS: {

View File

@@ -15,12 +15,13 @@ export const VCMetamodel = createModel(
inProgressVcDownloads: new Set<string>(), //VCDownloadInProgress
areAllVcsDownloaded: false as boolean,
walletBindingSuccess: false,
autoWalletBindingSuccess: true,
tamperedVcs: [] as VCMetadata[],
downloadingFailedVcs: [] as VCMetadata[], //VCDownloadFailed
verificationErrorMessage: '' as string,
verificationStatus: null as vcVerificationBannerDetails | null,
DownloadingCredentialsFailed: false,
DownloadingCredentialsSuccess: false
DownloadingCredentialsSuccess: false,
},
{
events: VcMetaEvents,

View File

@@ -68,6 +68,10 @@ export function selectWalletBindingSuccess(state: State) {
return state.context.walletBindingSuccess;
}
export function selectAutoWalletBindingSuccess(state: State) {
return state.context.autoWalletBindingSuccess;
}
export function selectIsTampered(state: State) {
return state.matches('ready.tamperedVCs');
}

View File

@@ -43,22 +43,24 @@ export interface CredentialSubject {
type VCContext = (string | Record<string, unknown>)[];
export type Credential = {
credentialConfigurationId: any;
'@context': VCContext;
credentialSubject: CredentialSubject;
id: string;
issuanceDate: string;
issuer: string;
proof: {
created: string;
jws: string;
proofPurpose: 'assertionMethod' | string;
type: 'RsaSignature2018' | string;
verificationMethod: string;
};
type: string[];
} | string
export type Credential =
| {
credentialConfigurationId: any;
'@context': VCContext;
credentialSubject: CredentialSubject;
id: string;
issuanceDate: string;
issuer: string;
proof: {
created: string;
jws: string;
proofPurpose: 'assertionMethod' | string;
type: 'RsaSignature2018' | string;
verificationMethod: string;
};
type: string[];
}
| string;
export interface VerifiableCredential {
issuerLogo: logoType;
@@ -84,6 +86,7 @@ export interface CredentialWrapper {
identifier: string;
generatedOn: Date;
vcMetadata: VCMetadata;
walletBindingResponse: WalletBindingResponse;
}
export interface CredentialTypes {

View File

@@ -84,8 +84,8 @@ export const MyVcsTab: React.FC<HomeScreenTabProps> = props => {
const credentialSubject =
vc.verifiableCredential.credentialSubject ||
vc.verifiableCredential.credential.credentialSubject;
if(isStringAndContains(searchText,vc['vcMetadata'].credentialType))
isVcFound=true
if (isStringAndContains(searchText, vc['vcMetadata'].credentialType))
isVcFound = true;
else if (credentialSubject) {
isVcFound = searchNestedCredentialFields(
searchTextLower,
@@ -449,7 +449,7 @@ export const MyVcsTab: React.FC<HomeScreenTabProps> = props => {
image={SvgImage.PermissionDenied()}
showClose={false}
primaryButtonText="goBack"
primaryButtonEvent={controller.RESET_VERIFY_ERROR}
primaryButtonEvent={controller.RESET_ERROR_SCREEN}
primaryButtonTestID="goBack"
customStyles={{marginTop: '30%'}}
/>

View File

@@ -107,8 +107,8 @@ export function useMyVcsTab(props: HomeScreenTabProps) {
DELETE_VC: () => vcMetaService?.send(VcMetaEvents.DELETE_VC()),
RESET_VERIFY_ERROR: () => {
vcMetaService?.send(VcMetaEvents.RESET_VERIFY_ERROR());
RESET_ERROR_SCREEN: () => {
vcMetaService?.send(VcMetaEvents.RESET_ERROR_SCREEN());
},
SET_TOUR_GUIDE: set => {
authService?.send(AuthEvents.SET_TOUR_GUIDE(set));

View File

@@ -14,6 +14,7 @@ import {
selectStoring,
selectVerificationErrorMessage,
selectIsNonGenericError,
selectAutoWalletBindingFailure,
} from '../../machines/Issuers/IssuersSelectors';
import {ActorRefFrom} from 'xstate';
import {BOTTOM_TAB_ROUTES} from '../../routes/routesConstants';
@@ -52,6 +53,10 @@ export function useIssuerScreenController({route, navigation}) {
service,
selectVerificationErrorMessage,
),
isAutoWalletBindingFailed: useSelector(
service,
selectAutoWalletBindingFailure,
),
isError: useSelector(service, selectIsError),
CANCEL: () => service.send(IssuerScreenTabEvents.CANCEL()),
@@ -65,8 +70,8 @@ export function useIssuerScreenController({route, navigation}) {
},
SELECTED_CREDENTIAL_TYPE: (credType: CredentialTypes) =>
service.send(IssuerScreenTabEvents.SELECTED_CREDENTIAL_TYPE(credType)),
RESET_VERIFY_ERROR: () => {
service.send(IssuerScreenTabEvents.RESET_VERIFY_ERROR());
RESET_ERROR_SCREEN: () => {
service.send(IssuerScreenTabEvents.RESET_ERROR_SCREEN());
if (isAndroid()) {
navigation.navigate(BOTTOM_TAB_ROUTES.home, {screen: 'HomeScreen'});
} else {

View File

@@ -51,6 +51,8 @@ export const IssuersScreen: React.FC<
? t(translationKey)
: t(`errors.verificationFailed.ERR_GENERIC`);
const isAutoWalletBindingFailed = controller.isAutoWalletBindingFailed;
useLayoutEffect(() => {
if (controller.loadingReason || showFullScreenError) {
props.navigation.setOptions({
@@ -170,7 +172,26 @@ export const IssuersScreen: React.FC<
image={SvgImage.PermissionDenied()}
showClose={false}
primaryButtonText="goBack"
primaryButtonEvent={controller.RESET_VERIFY_ERROR}
primaryButtonEvent={controller.RESET_ERROR_SCREEN}
primaryButtonTestID="goBack"
customStyles={{marginTop: '30%'}}
/>
);
}
if (isAutoWalletBindingFailed) {
return (
<Error
testID="autoWalletBindingError"
isVisible={isAutoWalletBindingFailed}
isModal={true}
alignActionsOnEnd
title={t('MyVcsTab:errors.autoWalletBindingError.title')}
message={t(`MyVcsTab:errors.autoWalletBindingError.message`)}
image={SvgImage.PermissionDenied()}
showClose={false}
primaryButtonText="goBack"
primaryButtonEvent={controller.RESET_ERROR_SCREEN}
primaryButtonTestID="goBack"
customStyles={{marginTop: '30%'}}
/>

View File

@@ -9,7 +9,7 @@ import {Protocols} from './openId4VCI/Utils';
import {getMosipIdentifier} from './commonUtil';
import {VCFormat} from './VCFormat';
import {isMosipVC} from './Utils';
import { getCredentialType } from '../components/VC/common/VCUtils';
import {getCredentialType} from '../components/VC/common/VCUtils';
const VC_KEY_PREFIX = 'VC';
const VC_ITEM_STORE_KEY_REGEX = '^VC_[a-zA-Z0-9_-]+$';
@@ -57,7 +57,7 @@ export class VCMetadata {
this.format = format;
this.downloadKeyType = downloadKeyType;
this.isExpired = isExpired;
this.credentialType = credentialType
this.credentialType = credentialType;
}
//TODO: Remove any typing and use appropriate typing
@@ -79,7 +79,7 @@ export class VCMetadata {
? vc.vcMetadata.mosipIndividualId
: getMosipIndividualId(vc.verifiableCredential, vc.issuer),
downloadKeyType: vc.downloadKeyType,
credentialType: vc.credentialType
credentialType: vc.credentialType,
});
}
@@ -119,7 +119,11 @@ export function parseMetadatas(metadataStrings: object[]) {
return metadataStrings.map(o => new VCMetadata(o));
}
export const getVCMetadata = (context: object, keyType: string, credType: CredentialTypes) => {
export const getVCMetadata = (
context: object,
keyType: string,
credType: CredentialTypes,
) => {
const [issuer, protocol, credentialId] =
context.credentialWrapper?.identifier.split(':');
@@ -137,7 +141,7 @@ export const getVCMetadata = (context: object, keyType: string, credType: Creden
),
format: context['credentialWrapper'].format,
downloadKeyType: keyType,
credentialType: getCredentialType(context.selectedCredentialType)
credentialType: getCredentialType(context.selectedCredentialType),
});
};
@@ -150,10 +154,7 @@ const getMosipIndividualId = (
? verifiableCredential.credential
: verifiableCredential;
const credentialSubject = credential?.credentialSubject;
if (isMosipVC(issuer)) {
return credentialSubject ? getMosipIdentifier(credentialSubject) : '';
}
return '';
return credentialSubject ? getMosipIdentifier(credentialSubject) : '';
} catch (error) {
console.error('Error getting the display ID:', error);
return null;

View File

@@ -63,6 +63,10 @@ export const removeWhiteSpace = (str: string) => {
return str ? str.replace(/\s/g, '') : str;
};
export const addPngBase64Prefix = (faceImage: string) => {
return faceImage ? 'data:image/png;base64,' + faceImage : faceImage;
};
export function logState(state: AnyState) {
if (__DEV__) {
const data = JSON.stringify(

View File

@@ -70,7 +70,7 @@ export const API_CACHED_STORAGE_KEYS = {
fetchIssuerWellknownConfig: (issuerId: string) =>
`CACHE_FETCH_ISSUER_WELLKNOWN_CONFIG_${issuerId}`,
fetchIssuerAuthorizationServerMetadata: (authorizationServerUrl: string) =>
`CACHE_FETCH_ISSUER_AUTHORIZATION_SERVER_METADATA_${authorizationServerUrl}`,
`CACHE_FETCH_ISSUER_AUTHORIZATION_SERVER_METADATA_${authorizationServerUrl}`,
fetchTrustedVerifiers: 'CACHE_FETCH_TRUSTED_VERIFIERS',
};
@@ -170,3 +170,5 @@ export const FACE_SDK_MODEL_CHECKSUM =
export const EXPIRED_VC_ERROR_CODE = 'ERR_VC_EXPIRED';
export const BASE_36 = 36;
export const DEFAULT_OTP = '111111';