diff --git a/.env b/.env
index ec478f88..b1bc3370 100644
--- a/.env
+++ b/.env
@@ -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
diff --git a/.github/scripts/set-google-clientid.sh b/.github/scripts/set-google-clientid.sh
index a5d6fb4c..679e9c67 100755
--- a/.github/scripts/set-google-clientid.sh
+++ b/.github/scripts/set-google-clientid.sh
@@ -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
diff --git a/.github/workflows/internal-build.yml b/.github/workflows/internal-build.yml
index baf3c6f4..54df5977 100644
--- a/.github/workflows/internal-build.yml
+++ b/.github/workflows/internal-build.yml
@@ -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 }}'
\ No newline at end of file
+ # SLACK_WEBHOOK_URL: '${{ secrets.SLACK_WEBHOOK_INJI_TEAM }}'
diff --git a/.talismanrc b/.talismanrc
index 23d77564..55f38ae5 100644
--- a/.talismanrc
+++ b/.talismanrc
@@ -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: ""
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 47d31d5c..7c457407 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -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 ->
diff --git a/android/fastlane/Fastfile b/android/fastlane/Fastfile
index d4c360d0..b5ed19bc 100644
--- a/android/fastlane/Fastfile
+++ b/android/fastlane/Fastfile
@@ -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
diff --git a/components/BannerNotificationContainer.tsx b/components/BannerNotificationContainer.tsx
index 5d18e6f9..70312cec 100644
--- a/components/BannerNotificationContainer.tsx
+++ b/components/BannerNotificationContainer.tsx
@@ -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<
)}
- {WalletBindingSuccess && (
-
-
-
- )}
+ {WalletBindingSuccess ||
+ (!autoWalletBindingSuccess && (
+
+
+
+ ))}
{showQuickShareSuccessBanner && (
diff --git a/components/BannerNotificationController.tsx b/components/BannerNotificationController.tsx
index cf5db6a4..decf8a96 100644
--- a/components/BannerNotificationController.tsx
+++ b/components/BannerNotificationController.tsx
@@ -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());
diff --git a/components/HelpScreen.tsx b/components/HelpScreen.tsx
index bf2719f6..314bd43d 100644
--- a/components/HelpScreen.tsx
+++ b/components/HelpScreen.tsx
@@ -189,21 +189,6 @@ export const HelpScreen: React.FC = props => {
{getTextField(t('answers.inji.eight'))}
),
},
- {
- title: t('questions.inji.nine'),
- data: (
-
- {getTextField(
- t('answers.inji.nine'),
- getLinkedText(
- injiHelpUrl +
- '/functional-overview/end-user-guide#activating-a-vc',
- t('here'),
- ),
- )}
-
- ),
- },
{
title: t('questions.inji.ten'),
data: (
@@ -220,14 +205,6 @@ export const HelpScreen: React.FC = props => {
),
},
- {
- title: t('questions.inji.eleven'),
- data: (
-
- {getTextField(t('answers.inji.eleven'))}
-
- ),
- },
{
title: t('questions.inji.twelve'),
data: (
diff --git a/components/VC/Views/VCCardViewContent.tsx b/components/VC/Views/VCCardViewContent.tsx
index e330ed1e..d7fd4070 100644
--- a/components/VC/Views/VCCardViewContent.tsx
+++ b/components/VC/Views/VCCardViewContent.tsx
@@ -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 = props => {
const wellknownDisplayProperty = new Display(props.wellknown);
@@ -53,7 +54,7 @@ export const VCCardViewContent: React.FC = props => {
/>
));
const issuerLogo = props.verifiableCredentialData.issuerLogo;
- const faceImage = props.verifiableCredentialData.face;
+ const faceImage = addPngBase64Prefix(props.verifiableCredentialData.face);
const {start} = useCopilot();
const {t} = useTranslation();
diff --git a/components/VC/Views/VCDetailView.tsx b/components/VC/Views/VCDetailView.tsx
index 38d02523..0b5d345e 100644
--- a/components/VC/Views/VCDetailView.tsx
+++ b/components/VC/Views/VCDetailView.tsx
@@ -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 (
);
diff --git a/components/VcItemContainerProfileImage.tsx b/components/VcItemContainerProfileImage.tsx
index fc65104d..1b8478de 100644
--- a/components/VcItemContainerProfileImage.tsx
+++ b/components/VcItemContainerProfileImage.tsx
@@ -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 ? (
{
@@ -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,
+ },
+ ),
};
};
diff --git a/machines/Issuers/IssuersEvents.ts b/machines/Issuers/IssuersEvents.ts
index 3aa94d77..2092e280 100644
--- a/machines/Issuers/IssuersEvents.ts
+++ b/machines/Issuers/IssuersEvents.ts
@@ -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: () => ({}),
};
diff --git a/machines/Issuers/IssuersGuards.ts b/machines/Issuers/IssuersGuards.ts
index 2cc8771b..383bec20 100644
--- a/machines/Issuers/IssuersGuards.ts
+++ b/machines/Issuers/IssuersGuards.ts
@@ -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,
};
};
diff --git a/machines/Issuers/IssuersMachine.ts b/machines/Issuers/IssuersMachine.ts
index e46f7ce3..19bf9909 100644
--- a/machines/Issuers/IssuersMachine.ts
+++ b/machines/Issuers/IssuersMachine.ts
@@ -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: [
diff --git a/machines/Issuers/IssuersModel.ts b/machines/Issuers/IssuersModel.ts
index e3f90f80..a5004c78 100644
--- a/machines/Issuers/IssuersModel.ts
+++ b/machines/Issuers/IssuersModel.ts
@@ -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,
diff --git a/machines/Issuers/IssuersSelectors.ts b/machines/Issuers/IssuersSelectors.ts
index 2c7b8b13..7983b785 100644
--- a/machines/Issuers/IssuersSelectors.ts
+++ b/machines/Issuers/IssuersSelectors.ts
@@ -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');
}
diff --git a/machines/Issuers/IssuersService.ts b/machines/Issuers/IssuersService.ts
index cd890b39..a47eaa8d 100644
--- a/machines/Issuers/IssuersService.ts
+++ b/machines/Issuers/IssuersService.ts
@@ -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;
+ },
};
};
diff --git a/machines/VerifiableCredential/VCMetaMachine/VCMetaActions.ts b/machines/VerifiableCredential/VCMetaMachine/VCMetaActions.ts
index 574395b9..0779c08c 100644
--- a/machines/VerifiableCredential/VCMetaMachine/VCMetaActions.ts
+++ b/machines/VerifiableCredential/VCMetaMachine/VCMetaActions.ts
@@ -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,
diff --git a/machines/VerifiableCredential/VCMetaMachine/VCMetaEvents.ts b/machines/VerifiableCredential/VCMetaMachine/VCMetaEvents.ts
index 8233bfa6..1d3e9955 100644
--- a/machines/VerifiableCredential/VCMetaMachine/VCMetaEvents.ts
+++ b/machines/VerifiableCredential/VCMetaMachine/VCMetaEvents.ts
@@ -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) => ({
diff --git a/machines/VerifiableCredential/VCMetaMachine/VCMetaMachine.ts b/machines/VerifiableCredential/VCMetaMachine/VCMetaMachine.ts
index 30f5b003..ec7c9206 100644
--- a/machines/VerifiableCredential/VCMetaMachine/VCMetaMachine.ts
+++ b/machines/VerifiableCredential/VCMetaMachine/VCMetaMachine.ts
@@ -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: {
diff --git a/machines/VerifiableCredential/VCMetaMachine/VCMetaModel.ts b/machines/VerifiableCredential/VCMetaMachine/VCMetaModel.ts
index 0e501b1f..83a4ff10 100644
--- a/machines/VerifiableCredential/VCMetaMachine/VCMetaModel.ts
+++ b/machines/VerifiableCredential/VCMetaMachine/VCMetaModel.ts
@@ -15,12 +15,13 @@ export const VCMetamodel = createModel(
inProgressVcDownloads: new Set(), //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,
diff --git a/machines/VerifiableCredential/VCMetaMachine/VCMetaSelectors.ts b/machines/VerifiableCredential/VCMetaMachine/VCMetaSelectors.ts
index 8fc9e2fc..0a8c7d49 100644
--- a/machines/VerifiableCredential/VCMetaMachine/VCMetaSelectors.ts
+++ b/machines/VerifiableCredential/VCMetaMachine/VCMetaSelectors.ts
@@ -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');
}
diff --git a/machines/VerifiableCredential/VCMetaMachine/vc.d.ts b/machines/VerifiableCredential/VCMetaMachine/vc.d.ts
index 0d1e1ef7..941bc219 100644
--- a/machines/VerifiableCredential/VCMetaMachine/vc.d.ts
+++ b/machines/VerifiableCredential/VCMetaMachine/vc.d.ts
@@ -43,22 +43,24 @@ export interface CredentialSubject {
type VCContext = (string | Record)[];
-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 {
diff --git a/screens/Home/MyVcsTab.tsx b/screens/Home/MyVcsTab.tsx
index cc903783..2579cc1c 100644
--- a/screens/Home/MyVcsTab.tsx
+++ b/screens/Home/MyVcsTab.tsx
@@ -84,8 +84,8 @@ export const MyVcsTab: React.FC = 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 = props => {
image={SvgImage.PermissionDenied()}
showClose={false}
primaryButtonText="goBack"
- primaryButtonEvent={controller.RESET_VERIFY_ERROR}
+ primaryButtonEvent={controller.RESET_ERROR_SCREEN}
primaryButtonTestID="goBack"
customStyles={{marginTop: '30%'}}
/>
diff --git a/screens/Home/MyVcsTabController.ts b/screens/Home/MyVcsTabController.ts
index 7473c49d..f892de80 100644
--- a/screens/Home/MyVcsTabController.ts
+++ b/screens/Home/MyVcsTabController.ts
@@ -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));
diff --git a/screens/Issuers/IssuerScreenController.tsx b/screens/Issuers/IssuerScreenController.tsx
index 4f582ec5..ec6d8e66 100644
--- a/screens/Issuers/IssuerScreenController.tsx
+++ b/screens/Issuers/IssuerScreenController.tsx
@@ -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 {
diff --git a/screens/Issuers/IssuersScreen.tsx b/screens/Issuers/IssuersScreen.tsx
index 8118c22b..98487b8c 100644
--- a/screens/Issuers/IssuersScreen.tsx
+++ b/screens/Issuers/IssuersScreen.tsx
@@ -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 (
+
diff --git a/shared/VCMetadata.ts b/shared/VCMetadata.ts
index 1e3ae00b..5c2fdfee 100644
--- a/shared/VCMetadata.ts
+++ b/shared/VCMetadata.ts
@@ -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;
diff --git a/shared/commonUtil.ts b/shared/commonUtil.ts
index b4af6775..ef5fb6be 100644
--- a/shared/commonUtil.ts
+++ b/shared/commonUtil.ts
@@ -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(
diff --git a/shared/constants.ts b/shared/constants.ts
index 6cbcbf3f..09d937a3 100644
--- a/shared/constants.ts
+++ b/shared/constants.ts
@@ -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';