diff --git a/.talismanrc b/.talismanrc
index 18ac4bf0..6e650aee 100644
--- a/.talismanrc
+++ b/.talismanrc
@@ -2,7 +2,7 @@ fileignoreconfig:
- filename: package.json
checksum: 5b4fcb5ddc7cc96cc2d1733b544d56ea66e88cdab995a1052fbf9ac0e9c2dc21
- filename: package-lock.json
- checksum: 50254c7e3e84d59dceb77cde95ce71cb5d0625cb5ec84971a28b6fc4f95db7f1
+ checksum: 98f4ef19f06521bac3ea3033d82810203214bf55b0469790a1d8acc20933c581
- filename: lib/jsonld-signatures/suites/ed255192018/ed25519.ts
checksum: 493b6e31144116cb612c24d98b97d8adcad5609c0a52c865a6847ced0a0ddc3a
- filename: components/PasscodeVerify.tsx
@@ -38,7 +38,7 @@ fileignoreconfig:
- filename: screens/Home/MyVcs/GetIdInputModal.tsx
checksum: 5c736ed79a372d0ffa7c02eb33d0dc06edbbb08d120978ff287f5f06cd6c7746
- filename: shared/openId4VCI/Utils.ts
- checksum: f8b53de9c07074dc3a73f9443ba140c7e86300b4a2beac1a84bfccafb55ecd6a
+ checksum: ee4db1768be8d51fac0eb876a7b16fd2ab1806abcc711f01056f672003d11f31
- filename: shared/cryptoutil/cryptoUtil.ts
checksum: 2efef1baca1eee0da60420c8d966a6d58589bc3ac74169ab1cdc19423b630dba
- filename: shared/telemetry/TelemetryConstants.js
@@ -63,8 +63,10 @@ fileignoreconfig:
checksum: 736b5a7ddb86bd4376229ce198dbf8a663e7ac89fc3311bd4f19afd4a2b36ffd
- filename: assets/Finger_Print_Icon.svg
checksum: 776d4fe4fc4b54d185ccf97daf0511b9fe2c0e0f7c1a809047020e5e8a100db6
+ - filename: screens/MainLayout.tsx
+ checksum: 53ead79279c9609e42a8993db1a66bdb4649e1ae3b909d462b45b00c507c416e
- filename: android/app/build.gradle
- checksum: 9f9cdcd2ffb37338760d741694486cf5418a38834c3ca1bd9c573098ee10d997
+ checksum: 46a4054440361b25d13ecd75811bf239a6abb4830ce7f79b2b15ccd878758760
- filename: .github/workflows/push-triggers.yml
checksum: abc19ea38c8d7b79f15695d015709cc88a34a995181aaf12bc8344f940f3cbc4
- filename: android/fastlane/Fastfile
@@ -113,6 +115,16 @@ fileignoreconfig:
checksum: a4e3772dc67a07ecbcfc58be0d6d4f7fa799cec7ac25bd269ac29459c8669ca4
- filename: injitest/src/test/java/iosTestCases/CredentialRegistryTest.java
checksum: b0808e0c511412cde21fd169a9bbeaf3b77cb48f25418e12d341cc3ce1df5898
+ - filename: injitest/src/main/resources/Vids.json
+ checksum: 8bcffed7a6dd565ae695e1b29de0655e10bd5c5420af2718defd593a687b8817
+ - filename: injitest/src/main/java/inji/utils/UpdateNetworkSettings.java
+ checksum: e249ce3e6b7f47abc183fe5a3637bb39ccb06900ef75b9b2f08426d1535e22aa
+ - filename: injitest/src/test/java/androidTestCases/ShareVcTest.java
+ checksum: a7e3e579b6ac05f95932638b61272142774d0690c13717c890e87374782ea509
+ - filename: injitest/src/test/java/iosTestCases/ShareVcTest.java
+ checksum: 1cf9b61d3fcea9b63b2b9f7dffe9b5a1848e196c39f77790b6c9d83f201c6197
+ - filename: ios/RNPixelpassModule.swift
+ checksum: 822a2421798d5c0669f4ab1b983194eb770cbef2aa30bf212d06bd959738c4ca
- filename: components/BackupAndRestoreAllScreenBanner.tsx
checksum: 2c98e7e83959c9dac4dd12da32f81483c3d334bd05e279637cf465475fbf54b8
- filename: locales/en.json
@@ -144,7 +156,7 @@ fileignoreconfig:
- filename: shared/VCMetadata.ts
checksum: e93f988415bf91064e2cf5fbc09ff6c7226798baa5da721fa0715d5d0d6afddf
- filename: ios/Podfile.lock
- checksum: 0b4ed806e0fbecf60fb1135072d0a629666723fedcd960b6470bac0bb42a3e68
+ checksum: b8c97d58a88207bae811db83074388cff249a83055a1f92ea7dee2f59b7a32c9
- filename: components/BackupAndRestoreBannerNotification.tsx
checksum: e465a9947727687d784d0cb9d8db1e28f765b0659bf4a3aa6d75643aa7b14102
- filename: components/ActivityLogEvent.ts
@@ -186,11 +198,11 @@ fileignoreconfig:
- filename: screens/Home/IntroSlidersScreen.tsx
checksum: 9880724461b194db7651737576ad2fd2db9cf3b4e732747f59be422a7ff4e4a1
- filename: .env
- checksum: e4254ca79a1269161ac3e9d4870680a8650ac7dbdf61c39c084722a9e8925669
+ checksum: ac76b852842c44ff5dac96c1fa5061e569bea4f54b3080d869a9dc25abd17991
- filename: machines/VCItemMachine/VCItemMachine.typegen.ts
checksum: 850b5d02636bef9e286fc0fbc4ffffbd38068f332c319302a906496f4bc1c8a1
- - filename: machines/VCItemMachine/VCItemEvents.ts
- checksum: 04e5758d4fa8bc37e8b66f7f51627a9e71ccbca7a046aa64e914f5cf855aa48b
+ - filename: machines/VerifiableCredential/VCItemMachine/VCItemModel.ts
+ checksum: 2a22331fe5f20d44c210b8970be0b934bfdf39bc999009305a9ba8f18e4d5469
- filename: machines/VCItemMachine/VCItemGaurds.ts
checksum: 4f32814fc26a0edaa54a42dbc9f9e1d899144eb059ac8da211d1738887871829
- filename: machines/VCItemMachine/VCItemServices.ts
@@ -317,8 +329,14 @@ fileignoreconfig:
- filename: machines/VerifiableCredential/VCItemMachine/VCItemMachine.ts
checksum: fdc0c23a7107eb713d20f60fda675f9e9fe8ef29c981d798d90e581dfee340c8
checksum: 8ac74d2e5c6de179e460b86899eb048ad4c5bd67abc3d28c015e92335b8afe24
+ - filename: machines/VerifiableCredential/VCItemMachine/VCItemServices.ts
+ checksum: 1ce38602f148388940eec172a5c9be83de7a600adcae0ba9e8ac27e5ebc44641
+ - filename: ios/RNPixelpassModule.m
+ checksum: c91348eceec5edbffa03ba03f3f52a8e90ff7f942816c9609080d1647052fd66
- filename: android/app/src/main/java/io/mosip/residentapp/InjiVciClientModule.java
checksum: 17f55840bab193bc353034445ba4fce53e1ce466e95f616c15a1351f8d2f23bc
+ - filename: ios/Inji.xcworkspace/xcshareddata/swiftpm/Package.resolved
+ checksum: b168940c6b487dc96fd22f564f2e187dae46f4fa5e4a64cf81c4d810b1c1ae78
- filename: injitest/src/main/resources/Vids.json
checksum: 8bcffed7a6dd565ae695e1b29de0655e10bd5c5420af2718defd593a687b8817
- filename: injitest/src/main/java/inji/utils/UpdateNetworkSettings.java
@@ -347,4 +365,8 @@ fileignoreconfig:
checksum: b168940c6b487dc96fd22f564f2e187dae46f4fa5e4a64cf81c4d810b1c1ae78
- filename: ios/Inji.xcodeproj/project.pbxproj
checksum: 4359976ed4d1ac3206d76b87d3458d070027199c8569ba123436c4b5343aba74
+ - filename: components/FaceScanner/FaceCompare.tsx
+ checksum: 947b6d75543e2bf959ca2d95dd7224051e0b4ec2c28f7515f923701e22a932f0
+ - filename: components/FaceScanner/LivenessDetection.tsx
+ checksum: d4140a42ee9ca0f7c90e490f762d181a723fd9dd20db891cbbe53bfbd8f81632
version: ""
diff --git a/__mocks__/jest-init.js b/__mocks__/jest-init.js
index 2268d229..c6952559 100644
--- a/__mocks__/jest-init.js
+++ b/__mocks__/jest-init.js
@@ -145,12 +145,9 @@ jest.mock('react-native-gesture-handler', () => {
};
});
-jest.mock('@mosip/secure-keystore', () => ({
- sign: jest.fn(),
- encryptData: input => (input ? String(input) : 'mockedString'),
- decryptData: input => (input ? String(input) : 'mockedString'),
- deviceSupportsHardware: () => true,
-}));
+jest.mock('@invertase/react-native-apple-authentication', () => {});
+
+jest.mock('react-native-share', () => {});
jest.mock('../machines/store', () => ({
getItem: jest.fn(),
diff --git a/__mocks__/react-native.mock.js b/__mocks__/react-native.mock.js
index 33464336..b4934147 100644
--- a/__mocks__/react-native.mock.js
+++ b/__mocks__/react-native.mock.js
@@ -17,6 +17,12 @@ jest.mock('react-native', () => {
SecureKeystore: {
deviceSupportsHardware: jest.fn(),
},
+ RNSecureKeystoreModule: {
+ sign: jest.fn(),
+ encryptData: input => (input ? String(input) : 'mockedString'),
+ decryptData: input => (input ? String(input) : 'mockedString'),
+ deviceSupportsHardware: () => true,
+ },
},
});
diff --git a/components/ActivityLogEvent.test.ts b/components/ActivityLogEvent.test.ts
index a5eb0d8d..85e9698f 100644
--- a/components/ActivityLogEvent.test.ts
+++ b/components/ActivityLogEvent.test.ts
@@ -23,7 +23,7 @@ describe('getActionText', () => {
mockIl18nfn = jest.fn();
activityLog = new ActivityLog({
id: 'mockId',
- idType: 'mockIDtype',
+ idType: ['mockIDtype'] as string[],
_vcKey: 'mock_vc_key',
type: 'mockType',
timestamp: 1234,
@@ -38,18 +38,17 @@ describe('getActionText', () => {
return 'National ID';
}
});
- getActionText(activityLog, mockIl18nfn);
- expect(mockIl18nfn).toHaveBeenCalledWith(`VcDetails:mockIDtype`);
+ getActionText(activityLog, mockIl18nfn, {});
expect(mockIl18nfn).toHaveBeenCalledWith('mockType', {
- idType: 'National ID',
+ idType: 'nationalCard',
id: 'mockId',
});
- expect(mockIl18nfn).toHaveBeenCalledTimes(2);
+ expect(mockIl18nfn).toHaveBeenCalledTimes(1);
// TODO: assert the returned string
});
it('should not fetch id type from translation file mock', () => {
activityLog.idType = undefined;
- getActionText(activityLog, mockIl18nfn);
+ getActionText(activityLog, mockIl18nfn, {});
expect(mockIl18nfn).toHaveBeenCalledWith('mockType', {
idType: '',
id: 'mockId',
diff --git a/components/ActivityLogEvent.ts b/components/ActivityLogEvent.ts
index eb789e53..a0b8e9a4 100644
--- a/components/ActivityLogEvent.ts
+++ b/components/ActivityLogEvent.ts
@@ -1,3 +1,5 @@
+import {getIdType} from './VC/common/VCUtils';
+
export type ActivityLogType =
| '' // replacement for undefined
| 'VC_SHARED'
@@ -18,21 +20,23 @@ export type ActivityLogType =
export class ActivityLog {
id: string;
- idType: string;
+ idType: string[];
_vcKey: string;
timestamp: number;
deviceName: string;
vcLabel: string;
type: ActivityLogType;
+ issuer: string;
constructor({
id = '',
- idType = '',
+ idType = [],
_vcKey = '',
type = '',
timestamp = Date.now(),
deviceName = '',
vcLabel = '',
+ issuer = '',
} = {}) {
this.id = id;
this.idType = idType;
@@ -41,6 +45,7 @@ export class ActivityLog {
this.timestamp = timestamp;
this.deviceName = deviceName;
this.vcLabel = vcLabel;
+ this.issuer = issuer;
}
static logTamperedVCs() {
@@ -50,13 +55,14 @@ export class ActivityLog {
timestamp: Date.now(),
deviceName: '',
vcLabel: '',
+ issuer: '',
};
}
}
-export function getActionText(activity: ActivityLog, t) {
- if (activity.idType && activity.idType !== '') {
- let cardType = t(`VcDetails:${activity.idType}`);
+export function getActionText(activity: ActivityLog, t, wellknown: Object) {
+ if (activity.idType && activity.idType.length !== 0) {
+ const cardType = getIdType(wellknown, activity.idType);
return `${t(activity.type, {idType: cardType, id: activity.id})}`;
}
return `${t(activity.type, {idType: '', id: activity.id})}`;
diff --git a/components/ActivityLogText.tsx b/components/ActivityLogText.tsx
index 44c192b2..dc885e31 100644
--- a/components/ActivityLogText.tsx
+++ b/components/ActivityLogText.tsx
@@ -5,15 +5,21 @@ import {useTranslation} from 'react-i18next';
import * as DateFnsLocale from 'date-fns/locale';
import {TextItem} from './ui/TextItem';
import {ActivityLog, getActionText} from './ActivityLogEvent';
+import {useHistoryTab} from '../screens/History/HistoryScreenController';
export const ActivityLogText: React.FC<{activity: ActivityLog}> = props => {
const {t, i18n} = useTranslation('ActivityLogText');
+ const historyController = useHistoryTab();
const {activity} = props;
return (
);
diff --git a/components/BannerNotificationContainer.tsx b/components/BannerNotificationContainer.tsx
index ecbd24f6..4d795788 100644
--- a/components/BannerNotificationContainer.tsx
+++ b/components/BannerNotificationContainer.tsx
@@ -78,9 +78,7 @@ export const BannerNotificationContainer: React.FC<
= ({
@@ -13,11 +13,11 @@ const FaceCompare: React.FC = ({
isCapturing,
isVerifying,
service,
- t
+ t,
}) => {
return (
-
-
+
+
= ({
align="center"
weight="semibold"
style={Theme.TextStyles.base}
- margin="80 57"
- >
+ margin="80 57">
{t('imageCaptureGuide')}
@@ -47,7 +46,9 @@ const FaceCompare: React.FC = ({
service.send('CAPTURE')}>
{SvgImage.CameraCaptureIcon()}
-
+
{t('capture')}
@@ -55,7 +56,9 @@ const FaceCompare: React.FC = ({
service.send('FLIP_CAMERA')}>
{SvgImage.FlipCameraIcon()}
-
+
{t('flipCamera')}
@@ -69,10 +72,10 @@ const FaceCompare: React.FC = ({
export default FaceCompare;
interface FaceCompareProps {
- whichCamera: CameraType;
- setCameraRef:(node: Camera) => void;
- isCapturing: boolean;
- isVerifying: boolean;
- service: any;
- t: (key: string) => string;
- }
\ No newline at end of file
+ whichCamera: CameraType;
+ setCameraRef: (node: Camera) => void;
+ isCapturing: boolean;
+ isVerifying: boolean;
+ service: any;
+ t: (key: string) => string;
+}
diff --git a/components/FaceScanner/FaceScannerHelper.ts b/components/FaceScanner/FaceScannerHelper.ts
index 7306b47e..1fb035bf 100644
--- a/components/FaceScanner/FaceScannerHelper.ts
+++ b/components/FaceScanner/FaceScannerHelper.ts
@@ -45,7 +45,7 @@ export const imageCaptureConfig = {
imageType: ImageType.jpg,
};
-export const faceDetectorConfig : FaceDetectorConfig= {
+export const faceDetectorConfig: FaceDetectorConfig = {
mode: FaceDetector.FaceDetectorMode.accurate,
detectLandmarks: FaceDetector.FaceDetectorLandmarks.all,
runClassifications: FaceDetector.FaceDetectorClassifications.all,
@@ -258,7 +258,7 @@ export interface FaceDetectorConfig {
mode: FaceDetector.FaceDetectorMode;
detectLandmarks: FaceDetector.FaceDetectorLandmarks;
runClassifications: FaceDetector.FaceDetectorClassifications;
- contourMode: FaceDetector.FaceDetectorClassifications;
+ contourMode: FaceDetector.FaceDetectorClassifications;
minDetectionInterval: number;
tracking: boolean;
-};
\ No newline at end of file
+}
diff --git a/components/FaceScanner/LivenessDetection.tsx b/components/FaceScanner/LivenessDetection.tsx
index f0237fff..d7df5d66 100644
--- a/components/FaceScanner/LivenessDetection.tsx
+++ b/components/FaceScanner/LivenessDetection.tsx
@@ -1,12 +1,12 @@
import React from 'react';
-import { Camera, CameraType } from 'expo-camera';
-import { View, TouchableOpacity } from 'react-native';
+import {Camera, CameraType} from 'expo-camera';
+import {View, TouchableOpacity} from 'react-native';
import Spinner from 'react-native-spinkit';
-import { Column, Text } from '.././ui';
-import { Theme } from '.././ui/styleUtils';
-import Svg, { Defs, Mask, Rect, Ellipse } from 'react-native-svg';
+import {Column, Text} from '.././ui';
+import {Theme} from '.././ui/styleUtils';
+import Svg, {Defs, Mask, Rect, Ellipse} from 'react-native-svg';
import testIDProps from '../../shared/commonUtil';
-import { FaceDetectorConfig } from './FaceScannerHelper';
+import {FaceDetectorConfig} from './FaceScannerHelper';
const LivenessDetection: React.FC = ({
screenColor,
@@ -18,19 +18,24 @@ const LivenessDetection: React.FC = ({
handleOnCancel,
opacity,
setOpacity,
- t
+ t,
}) => {
return (
-
+
-
+
{infoText}
-
+
= ({
onFacesDetected={handleFacesDetected}
faceDetectorSettings={faceDetectorConfig}
/>
-
@@ -56,12 +66,16 @@ const LivenessDetection: React.FC = ({
setOpacity(0.5)}
onPressOut={() => setOpacity(1)}
- onPress={handleOnCancel}
- >
-
+ onPress={handleOnCancel}>
+
{t('cancel')}
@@ -73,14 +87,14 @@ const LivenessDetection: React.FC = ({
export default LivenessDetection;
interface LivenessDetectionProps {
- screenColor: string;
- infoText: string;
- whichCamera: CameraType;
- setCameraRef: (node: Camera) => void;
- handleFacesDetected: (faces: any) => Promise;
- faceDetectorConfig: FaceDetectorConfig;
- handleOnCancel: () => void;
- opacity: number;
- setOpacity: (opacity: number) => void;
- t: (key: string) => string;
- }
\ No newline at end of file
+ screenColor: string;
+ infoText: string;
+ whichCamera: CameraType;
+ setCameraRef: (node: Camera) => void;
+ handleFacesDetected: (faces: any) => Promise;
+ faceDetectorConfig: FaceDetectorConfig;
+ handleOnCancel: () => void;
+ opacity: number;
+ setOpacity: (opacity: number) => void;
+ t: (key: string) => string;
+}
diff --git a/components/VC/Views/VCCardViewContent.tsx b/components/VC/Views/VCCardViewContent.tsx
index 84ab3d49..0651933f 100644
--- a/components/VC/Views/VCCardViewContent.tsx
+++ b/components/VC/Views/VCCardViewContent.tsx
@@ -3,7 +3,7 @@ import {ImageBackground, Pressable, Image, View} from 'react-native';
import {getLocalizedField} from '../../../i18n';
import {VCMetadata} from '../../../shared/VCMetadata';
import {KebabPopUp} from '../../KebabPopUp';
-import {VerifiableCredential} from '../../../machines/VerifiableCredential/VCMetaMachine/vc';
+import {Credential} from '../../../machines/VerifiableCredential/VCMetaMachine/vc';
import {Column, Row} from '../../ui';
import {Theme} from '../../ui/styleUtils';
import {CheckBox, Icon} from 'react-native-elements';
@@ -13,7 +13,7 @@ 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 {isActivationNeeded} from '../../../shared/openId4VCI/Utils';
import {VCItemContainerFlowType} from '../../../shared/Utils';
import {RemoveVcWarningOverlay} from '../../../screens/Home/MyVcs/RemoveVcWarningOverlay';
import {HistoryTab} from '../../../screens/Home/MyVcs/HistoryTab';
@@ -87,10 +87,10 @@ export const VCCardViewContent: React.FC = props => {
{!Object.values(VCItemContainerFlowType).includes(props.flow) && (
<>
- {props.vcMetadata.issuer === Issuers.Sunbird ||
- props.walletBindingResponse
- ? SvgImage.walletActivatedIcon()
- : SvgImage.walletUnActivatedIcon()}
+ {!props.walletBindingResponse &&
+ isActivationNeeded(props.verifiableCredentialData?.issuer)
+ ? SvgImage.walletUnActivatedIcon()
+ : SvgImage.walletActivatedIcon()}
= props => {
export interface VCItemContentProps {
context: any;
- credential: VerifiableCredential;
+ credential: Credential;
verifiableCredentialData: any;
fields: [];
wellknown: {};
diff --git a/components/VC/Views/VCDetailView.tsx b/components/VC/Views/VCDetailView.tsx
index 363b8128..e2f2530f 100644
--- a/components/VC/Views/VCDetailView.tsx
+++ b/components/VC/Views/VCDetailView.tsx
@@ -2,6 +2,7 @@ import React from 'react';
import {useTranslation} from 'react-i18next';
import {Image, ImageBackground, View} from 'react-native';
import {
+ Credential,
VerifiableCredential,
WalletBindingResponse,
} from '../../../machines/VerifiableCredential/VCMetaMachine/vc';
diff --git a/components/VC/common/VCUtils.tsx b/components/VC/common/VCUtils.tsx
index 4c6b5909..d9c7f60c 100644
--- a/components/VC/common/VCUtils.tsx
+++ b/components/VC/common/VCUtils.tsx
@@ -1,5 +1,8 @@
import {
+ Credential,
CredentialSubject,
+ CredentialTypes,
+ IssuerWellknownResponse,
VerifiableCredential,
} from '../../../machines/VerifiableCredential/VCMetaMachine/vc';
import i18n, {getLocalizedField} from '../../../i18n';
@@ -8,10 +11,10 @@ import {VCItemField} from './VCItemField';
import React from 'react';
import {Theme} from '../../ui/styleUtils';
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';
+import {VCItemDetailsProps} from '../Views/VCDetailView';
+import {getSelectedCredentialTypeDetails} from '../../../shared/openId4VCI/Utils';
export const CARD_VIEW_DEFAULT_FIELDS = ['fullName'];
export const DETAIL_VIEW_DEFAULT_FIELDS = [
@@ -26,8 +29,6 @@ export const DETAIL_VIEW_DEFAULT_FIELDS = [
//todo UIN & VID to be removed once we get the fields in the wellknown endpoint
export const CARD_VIEW_ADD_ON_FIELDS = ['UIN', 'VID'];
export const DETAIL_VIEW_ADD_ON_FIELDS = [
- 'UIN',
- 'VID',
'status',
'credentialRegistry',
'idType',
@@ -46,18 +47,11 @@ export const BOTTOM_SECTION_FIELDS_WITH_DETAILED_ADDRESS_FIELDS = [
];
export const getFieldValue = (
- verifiableCredential: VerifiableCredential,
+ verifiableCredential: Credential,
field: string,
wellknown: any,
props: any,
) => {
- const {t} = useTranslation();
- const date = new Date(
- getLocalizedField(verifiableCredential?.credentialSubject[field]),
- ).toString();
- if (date !== 'Invalid Date') {
- return formattedDateTime(date);
- }
switch (field) {
case 'status':
return (
@@ -67,7 +61,7 @@ export const getFieldValue = (
/>
);
case 'idType':
- return t(`VcDetails:${getIDType(verifiableCredential)}`);
+ return getIdType(wellknown);
case 'credentialRegistry':
return props?.vc?.credentialRegistry;
case 'address':
@@ -77,51 +71,22 @@ export const getFieldValue = (
default: {
const fieldValue = verifiableCredential?.credentialSubject[field];
if (Array.isArray(fieldValue) && typeof fieldValue[0] !== 'object') {
- return fieldValue;
+ return fieldValue.join(', ');
}
return getLocalizedField(fieldValue);
}
}
};
-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 credentialDefinition = getCredentialDefinition(
- wellknown,
- vcCredentialTypes,
- );
+export const getFieldName = (field: string, wellknown: any) => {
+ if (wellknown) {
+ const credentialDefinition = wellknown.credential_definition;
if (!credentialDefinition) {
console.error(
'Credential definition is not available for the selected credential type',
);
}
- let fieldObj = credentialDefinition.credentialSubject[field];
+ let fieldObj = credentialDefinition?.credentialSubject[field];
if (fieldObj) {
const newFieldObj = fieldObj.display.map(obj => {
return {language: obj.locale, value: obj.name};
@@ -133,20 +98,11 @@ export const getFieldName = (
};
export const getBackgroundColour = (wellknown: any) => {
- if (wellknown && wellknown.credentials_supported[0]?.display) {
- return {
- backgroundColor: wellknown.credentials_supported[0].display[0]
- ?.background_color
- ? wellknown.credentials_supported[0].display[0].background_color
- : Theme.Colors.textValue,
- };
- }
+ return wellknown?.display[0]?.background_color ?? Theme.Colors.textValue;
};
export const getTextColor = (wellknown: any, defaultColor: string) => {
- return (
- wellknown?.credentials_supported[0]?.display[0]?.text_color ?? defaultColor
- );
+ return wellknown?.display[0]?.text_color ?? defaultColor;
};
export function getAddressFields() {
@@ -174,26 +130,14 @@ function getFullAddress(credential: CredentialSubject) {
.join(', ');
}
-function formattedDateTime(timeStamp: any) {
- if (timeStamp) {
- const options = {year: 'numeric', month: '2-digit', day: '2-digit'};
- return new Date(timeStamp).toLocaleDateString('en-US', options);
- }
- return timeStamp;
-}
-
export const fieldItemIterator = (
fields: any[],
- verifiableCredential: any,
+ verifiableCredential: VerifiableCredential | Credential,
wellknown: any,
- props: any,
+ props: VCItemDetailsProps,
) => {
return fields.map(field => {
- const fieldName = getFieldName(
- field,
- wellknown,
- props.verifiableCredentialData.vcCredentialTypes,
- );
+ const fieldName = getFieldName(field, wellknown);
const fieldValue = getFieldValue(
verifiableCredential,
field,
@@ -225,7 +169,10 @@ export const fieldItemIterator = (
});
};
-export const isVCLoaded = (verifiableCredential: any, fields: string[]) => {
+export const isVCLoaded = (
+ verifiableCredential: Credential,
+ fields: string[],
+) => {
return verifiableCredential != null && fields.length > 0;
};
@@ -235,3 +182,50 @@ export const getMosipLogo = () => {
alt_text: 'a square logo of mosip',
};
};
+
+/**
+ *
+ * @param wellknown (either supportedCredential's wellknown or whole well known response of issuer)
+ * @param idType
+ * @returns id Type translations (Eg - National ID)
+ *
+ * supportedCredential's wellknown is passed from getActivityText after fresh download
+ * & all other consumers pass whole well known response of issuer
+ */
+export const getIdType = (
+ wellknown: CredentialTypes | IssuerWellknownResponse,
+ idType?: string[],
+) => {
+ if (wellknown && wellknown?.display) {
+ const idTypeObj = wellknown.display.map((displayProps: any) => {
+ return {language: displayProps.locale, value: displayProps.name};
+ });
+ return getLocalizedField(idTypeObj);
+ } else if (
+ wellknown &&
+ Object.keys(wellknown).length > 0 &&
+ idType !== undefined
+ ) {
+ let supportedCredentialsWellknown;
+ wellknown = JSON.parse(wellknown) as Object[];
+ if (!!!wellknown['credentials_supported']) {
+ return i18n.t('VcDetails:nationalCard');
+ }
+ supportedCredentialsWellknown = getSelectedCredentialTypeDetails(
+ wellknown,
+ idType,
+ );
+ if (Object.keys(supportedCredentialsWellknown).length === 0) {
+ return i18n.t('VcDetails:nationalCard');
+ }
+ return getIdType(supportedCredentialsWellknown);
+ } else {
+ return i18n.t('VcDetails:nationalCard');
+ }
+};
+
+export const getCredentialTypes = (
+ credential: Credential | VerifiableCredential,
+): string[] => {
+ return (credential?.credentialTypes as string[]) ?? ['VerifiableCredential'];
+};
diff --git a/components/ui/Modal.tsx b/components/ui/Modal.tsx
index 6ddd3265..ddc39478 100644
--- a/components/ui/Modal.tsx
+++ b/components/ui/Modal.tsx
@@ -19,64 +19,65 @@ export const Modal: React.FC = props => {
visible={props.isVisible}
onShow={props.onShow}
onRequestClose={props.onDismiss}>
-
- { props.showHeader ? (
-
-
- {props.headerRight && !props.arrowLeft ? (
-
- ) : null}
- {props.arrowLeft && props.onDismiss ? (
-
- ) : null}
-
-
-
- {props.headerTitle || props.headerLeft}
-
- {!props.requester ? (
-
- {props.headerLabel}
-
- ) : (
-
-
-
- )}
-
-
- {props.headerRight != null ||
- props.arrowLeft ||
- (props.showClose && (
+
+ {props.showHeader ? (
+
+
+ {props.headerRight && !props.arrowLeft ? (
- ))}
- {props.headerRight && props.headerRight}
-
-
) : null}
+ ) : null}
+ {props.arrowLeft && props.onDismiss ? (
+
+ ) : null}
+
+
+
+ {props.headerTitle || props.headerLeft}
+
+ {!props.requester ? (
+
+ {props.headerLabel}
+
+ ) : (
+
+
+
+ )}
+
+
+ {props.headerRight != null ||
+ props.arrowLeft ||
+ (props.showClose && (
+
+ ))}
+ {props.headerRight && props.headerRight}
+
+
+ ) : null}
{props.children}
diff --git a/components/ui/svg.tsx b/components/ui/svg.tsx
index 67beba4d..e17f8b38 100644
--- a/components/ui/svg.tsx
+++ b/components/ui/svg.tsx
@@ -21,7 +21,7 @@ import ReceiveCard from '../../assets/Receive_Card.svg';
import ReceivedCards from '../../assets/Received_Cards.svg';
import ProgressIcon from '../../assets/Progress_Icon1.svg';
import testIDProps from '../../shared/commonUtil';
-import Logo from '../../assets/Inji_Logo';
+import Logo from '../../assets/Inji_Logo.svg';
import WarningLogo from '../../assets/Warning_Icon.svg';
import OtpVerificationIcon from '../../assets/Otp_Verification_Icon.svg';
import FlipCameraIcon from '../../assets/Flip_Camera_Icon.svg';
diff --git a/components/ui/themes/DefaultTheme.ts b/components/ui/themes/DefaultTheme.ts
index bb45bb74..5e0ade88 100644
--- a/components/ui/themes/DefaultTheme.ts
+++ b/components/ui/themes/DefaultTheme.ts
@@ -1549,8 +1549,8 @@ export const DefaultTheme = {
},
scannerContainer: {
borderRadius: 24,
- height: 320,
- width: 300,
+ height: 350,
+ width: 320,
marginTop: 40,
backgroundColor: Colors.White,
borderWidth: 1,
@@ -1559,12 +1559,11 @@ export const DefaultTheme = {
}),
CameraEnabledStyles: StyleSheet.create({
- container: {marginTop: 20, marginBottom: 20},
scannerContainer: {
borderRadius: 24,
alignSelf: 'center',
- height: 320,
- width: 300,
+ height: 350,
+ width: 320,
overflow: 'hidden',
},
scanner: {
diff --git a/components/ui/themes/PurpleTheme.ts b/components/ui/themes/PurpleTheme.ts
index 3e8201b0..7ce5e01e 100644
--- a/components/ui/themes/PurpleTheme.ts
+++ b/components/ui/themes/PurpleTheme.ts
@@ -1549,8 +1549,8 @@ export const PurpleTheme = {
},
scannerContainer: {
borderRadius: 24,
- height: 320,
- width: 300,
+ height: 350,
+ width: 320,
marginTop: 40,
backgroundColor: Colors.White,
borderWidth: 1,
@@ -1558,12 +1558,11 @@ export const PurpleTheme = {
},
}),
CameraEnabledStyles: StyleSheet.create({
- container: {marginTop: 20, marginBottom: 20},
scannerContainer: {
borderRadius: 24,
alignSelf: 'center',
- height: 320,
- width: 300,
+ height: 350,
+ width: 320,
overflow: 'hidden',
},
scanner: {
diff --git a/machines/Issuers/IssuersActions.ts b/machines/Issuers/IssuersActions.ts
index 4c1fcf25..77fd52a2 100644
--- a/machines/Issuers/IssuersActions.ts
+++ b/machines/Issuers/IssuersActions.ts
@@ -1,9 +1,4 @@
-import {
- ErrorMessage,
- getIdType,
- Issuers_Key_Ref,
- updateVCmetadataOfCredentialWrapper,
-} from '../../shared/openId4VCI/Utils';
+import {ErrorMessage, Issuers_Key_Ref} from '../../shared/openId4VCI/Utils';
import {
MY_VCS_STORE_KEY,
NETWORK_REQUEST_FAILED,
@@ -61,12 +56,12 @@ export const IssuersActions = (model: any) => {
setSelectedCredentialType: model.assign({
selectedCredentialType: (_: any, event: any) => event.credType,
}),
+ setSupportedCredentialTypes: model.assign({
+ supportedCredentialTypes: (_: any, event: any) => event.data,
+ }),
resetSelectedCredentialType: model.assign({
selectedCredentialType: {},
}),
- setCredentialTypes: model.assign({
- credentialTypes: (_: any, event: any) => event.data.supportedCredentials,
- }),
setError: model.assign({
errorMessage: (_: any, event: any) => {
console.error('Error occurred ', event.data.message);
@@ -119,10 +114,10 @@ export const IssuersActions = (model: any) => {
),
setMetadataInCredentialData: (context: any) => {
- return updateVCmetadataOfCredentialWrapper(
- context,
- context.credentialWrapper,
- );
+ context.credentialWrapper = {
+ ...context.credentialWrapper,
+ vcMetadata: context.vcMetadata,
+ };
},
setVCMetadata: assign({
@@ -132,11 +127,13 @@ export const IssuersActions = (model: any) => {
}),
storeVerifiableCredentialData: send(
- (context: any) =>
- StoreEvents.SET(getVCMetadata(context).getVcKey(), {
+ (context: any) => {
+ const vcMeatadata = getVCMetadata(context);
+ return StoreEvents.SET(vcMeatadata.getVcKey(), {
...context.credentialWrapper,
- vcMetadata: getVCMetadata(context),
- }),
+ vcMetadata: vcMeatadata,
+ });
+ },
{
to: (context: any) => context.serviceRefs.store,
},
@@ -201,15 +198,21 @@ export const IssuersActions = (model: any) => {
logDownloaded: send(
context => {
- return ActivityLogEvents.LOG_ACTIVITY({
- _vcKey: getVCMetadata(context).getVcKey(),
- type: 'VC_DOWNLOADED',
- id: getVCMetadata(context).id,
- idType: getIdType(getVCMetadata(context).issuer),
- timestamp: Date.now(),
- deviceName: '',
- vcLabel: getVCMetadata(context).id,
- });
+ const vcMetadata = getVCMetadata(context);
+ return ActivityLogEvents.LOG_ACTIVITY(
+ {
+ _vcKey: vcMetadata.getVcKey(),
+ type: 'VC_DOWNLOADED',
+ id: vcMetadata.id,
+ idType:
+ context.credentialWrapper.verifiableCredential.credentialTypes,
+ timestamp: Date.now(),
+ deviceName: '',
+ vcLabel: vcMetadata.id,
+ issuer: context.selectedIssuerId,
+ },
+ context.selectedCredentialType,
+ );
},
{
to: (context: any) => context.serviceRefs.activityLog,
diff --git a/machines/Issuers/IssuersGuards.ts b/machines/Issuers/IssuersGuards.ts
index 37c388b9..707bb358 100644
--- a/machines/Issuers/IssuersGuards.ts
+++ b/machines/Issuers/IssuersGuards.ts
@@ -1,8 +1,8 @@
import {isSignedInResult} from '../../shared/CloudBackupAndRestoreUtils';
-import {ErrorMessage, Issuers, OIDCErrors} from '../../shared/openId4VCI/Utils';
+import {ErrorMessage, OIDCErrors} from '../../shared/openId4VCI/Utils';
import {isHardwareKeystoreExists} from '../../shared/cryptoutil/cryptoUtil';
import {BiometricCancellationError} from '../../shared/error/BiometricCancellationError';
-import {NETWORK_REQUEST_FAILED, REQUEST_TIMEOUT} from '../../shared/constants';
+import {NETWORK_REQUEST_FAILED} from '../../shared/constants';
import {VerificationErrorType} from '../../shared/vcjs/verifyCredential';
export const IssuersGuards = () => {
@@ -12,9 +12,6 @@ export const IssuersGuards = () => {
isSignedIn: (_: any, event: any) =>
(event.data as isSignedInResult).isSignedIn,
hasKeyPair: (context: any) => !!context.publicKey,
- isMultipleCredentialsSupported: (context: any, event: any) =>
- event.data.supportedCredentials.length > 1 &&
- context.selectedIssuer.credential_issuer === Issuers.Sunbird,
isInternetConnected: (_: any, event: any) => !!event.data.isConnected,
isOIDCflowCancelled: (_: any, event: any) => {
// iOS & Android have different error strings for user cancelled flow
diff --git a/machines/Issuers/IssuersMachine.ts b/machines/Issuers/IssuersMachine.ts
index d3e30562..a6861be2 100644
--- a/machines/Issuers/IssuersMachine.ts
+++ b/machines/Issuers/IssuersMachine.ts
@@ -1,9 +1,9 @@
import {EventFrom, send, sendParent} from 'xstate';
-import {log} from 'xstate/lib/actions';
import {IssuersModel} from './IssuersModel';
import {IssuersActions} from './IssuersActions';
import {IssuersService} from './IssuersService';
import {IssuersGuards} from './IssuersGuards';
+import {CredentialTypes} from '../VerifiableCredential/VCMetaMachine/vc';
const model = IssuersModel;
@@ -106,8 +106,7 @@ export const IssuersMachine = model.createMachine(
src: 'downloadCredentialTypes',
onDone: [
{
- actions: 'setCredentialTypes',
- cond: 'isMultipleCredentialsSupported',
+ actions: 'setSupportedCredentialTypes',
target: 'selectingCredentialType',
},
{
@@ -126,10 +125,7 @@ export const IssuersMachine = model.createMachine(
target: 'displayIssuers',
},
SELECTED_CREDENTIAL_TYPE: {
- actions: [
- (_, event) => console.log('>>>>> event', event),
- 'setSelectedCredentialType',
- ],
+ actions: 'setSelectedCredentialType',
target: 'checkInternet',
},
},
@@ -413,9 +409,11 @@ export interface logoType {
export interface displayType {
name: string;
- logo: logoType;
- language: string;
locale: string;
+ language: string;
+ logo: logoType;
+ background_color: string;
+ text_color: string;
title: string;
description: string;
}
@@ -426,14 +424,12 @@ export interface issuerType {
client_id: string;
'.well-known': string;
redirect_uri: string;
- scopes_supported: [string];
additional_headers: object;
authorization_endpoint: string;
- authorization_alias: string;
token_endpoint: string;
proxy_token_endpoint: string;
credential_endpoint: string;
- credential_type: [string];
credential_audience: string;
display: [displayType];
+ credentialTypes: [CredentialTypes];
}
diff --git a/machines/Issuers/IssuersMachine.typegen.ts b/machines/Issuers/IssuersMachine.typegen.ts
index 4a0a5e44..78a7eb28 100644
--- a/machines/Issuers/IssuersMachine.typegen.ts
+++ b/machines/Issuers/IssuersMachine.typegen.ts
@@ -104,7 +104,6 @@ export interface Typegen0 {
| 'sendErrorEndEvent'
| 'sendImpressionEvent'
| 'sendSuccessEndEvent'
- | 'setCredentialTypes'
| 'setCredentialWrapper'
| 'setError'
| 'setIsVerified'
@@ -120,6 +119,7 @@ export interface Typegen0 {
| 'setSelectedCredentialType'
| 'setSelectedIssuerId'
| 'setSelectedIssuers'
+ | 'setSupportedCredentialTypes'
| 'setTokenResponse'
| 'setVCMetadata'
| 'setVerifiableCredential'
@@ -137,7 +137,6 @@ export interface Typegen0 {
| 'isCustomSecureKeystore'
| 'isGenericError'
| 'isInternetConnected'
- | 'isMultipleCredentialsSupported'
| 'isOIDCConfigError'
| 'isOIDCflowCancelled'
| 'isSignedIn'
@@ -186,7 +185,6 @@ export interface Typegen0 {
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]'
@@ -216,6 +214,7 @@ export interface Typegen0 {
setSelectedCredentialType: 'SELECTED_CREDENTIAL_TYPE';
setSelectedIssuerId: 'SELECTED_ISSUER';
setSelectedIssuers: 'done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]';
+ setSupportedCredentialTypes: 'done.invoke.issuersMachine.downloadCredentialTypes:invocation[0]';
setTokenResponse: 'done.invoke.issuersMachine.performAuthorization:invocation[0]';
setVCMetadata:
| 'done.invoke.issuersMachine.verifyingCredential:invocation[0]'
@@ -244,7 +243,6 @@ export interface Typegen0 {
isCustomSecureKeystore: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
isGenericError: 'error.platform.issuersMachine.downloadCredentials: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]';
diff --git a/machines/Issuers/IssuersModel.ts b/machines/Issuers/IssuersModel.ts
index a799e617..5d6df08c 100644
--- a/machines/Issuers/IssuersModel.ts
+++ b/machines/Issuers/IssuersModel.ts
@@ -20,7 +20,7 @@ export const IssuersModel = createModel(
loadingReason: 'displayIssuers' as string,
verifiableCredential: null as VerifiableCredential | null,
selectedCredentialType: {} as CredentialTypes,
- credentialTypes: [] as CredentialTypes[],
+ supportedCredentialTypes: [] as CredentialTypes[],
credentialWrapper: {} as CredentialWrapper,
serviceRefs: {} as AppServices,
verificationErrorMessage: '',
diff --git a/machines/Issuers/IssuersSelectors.ts b/machines/Issuers/IssuersSelectors.ts
index 1a661b79..ec193b75 100644
--- a/machines/Issuers/IssuersSelectors.ts
+++ b/machines/Issuers/IssuersSelectors.ts
@@ -54,6 +54,6 @@ export function selectSelectingCredentialType(state: State) {
return state.matches('selectingCredentialType');
}
-export function selectCredentialTypes(state: State) {
- return state.context.credentialTypes;
+export function selectSupportedCredentialTypes(state: State) {
+ return state.context.supportedCredentialTypes;
}
diff --git a/machines/Issuers/IssuersService.ts b/machines/Issuers/IssuersService.ts
index b8ed6a44..7cb7c484 100644
--- a/machines/Issuers/IssuersService.ts
+++ b/machines/Issuers/IssuersService.ts
@@ -1,12 +1,9 @@
import Cloud from '../../shared/CloudBackupAndRestoreUtils';
-import {API_URLS, CACHED_API} from '../../shared/api';
+import {CACHED_API} from '../../shared/api';
import NetInfo from '@react-native-community/netinfo';
-import {request} from '../../shared/request';
import {
constructAuthorizationConfiguration,
constructProofJWT,
- getCredentialType,
- Issuers,
Issuers_Key_Ref,
updateCredentialInformation,
vcDownloadTimeout,
@@ -17,7 +14,6 @@ import {
isHardwareKeystoreExists,
} from '../../shared/cryptoutil/cryptoUtil';
import {NativeModules} from 'react-native';
-import {getVCMetadata, VCMetadata} from '../../shared/VCMetadata';
import {
VerificationErrorType,
verifyCredential,
@@ -27,6 +23,7 @@ import {
sendImpressionEvent,
} from '../../shared/telemetry/TelemetryUtils';
import {TelemetryConstants} from '../../shared/telemetry/TelemetryConstants';
+import {isMosipVC} from '../../shared/Utils';
import {VciClient} from '../../shared/vciClient/VciClient';
const {RNSecureKeystoreModule} = NativeModules;
@@ -43,20 +40,18 @@ export const IssuersService = () => {
let issuersConfig = await CACHED_API.fetchIssuerConfig(
context.selectedIssuerId,
);
- if (context.selectedIssuer['.well-known']) {
- await CACHED_API.fetchIssuerWellknownConfig(
- context.selectedIssuerId,
- context.selectedIssuer['.well-known'],
- );
- }
+ const wellknownResponse = await CACHED_API.fetchIssuerWellknownConfig(
+ context.selectedIssuerId,
+ issuersConfig['.well-known'],
+ );
+ issuersConfig.credential_endpoint =
+ wellknownResponse?.credential_endpoint;
+ issuersConfig.credential_audience = wellknownResponse?.credential_issuer;
+ issuersConfig.credentialTypes = wellknownResponse?.credentials_supported;
return issuersConfig;
},
downloadCredentialTypes: async (context: any) => {
- const response = await request(
- API_URLS.credentialTypes.method,
- API_URLS.credentialTypes.buildURL(context.selectedIssuerId),
- );
- return response?.response;
+ return context.selectedIssuer.credentialTypes;
},
downloadCredential: async (context: any) => {
const downloadTimeout = await vcDownloadTimeout();
@@ -65,7 +60,8 @@ export const IssuersService = () => {
credentialAudience: context.selectedIssuer.credential_audience,
credentialEndpoint: context.selectedIssuer.credential_endpoint,
downloadTimeoutInMilliSeconds: downloadTimeout,
- credentialType: getCredentialType(context),
+ credentialType: context.selectedCredentialType?.credential_definition
+ .type ?? ['VerifiableCredential'],
credentialFormat: 'ldp_vc',
};
const proofJWT = await constructProofJWT(
@@ -81,8 +77,7 @@ export const IssuersService = () => {
);
console.info(`VC download via ${context.selectedIssuerId} is successful`);
- credential = updateCredentialInformation(context, credential);
- return credential;
+ return updateCredentialInformation(context, credential);
},
invokeAuthorization: async (context: any) => {
sendImpressionEvent(
@@ -92,16 +87,10 @@ export const IssuersService = () => {
TelemetryConstants.Screens.webViewPage,
),
);
- let supportedScopes: [string];
- if (Object.keys(context.selectedCredentialType).length === 0) {
- supportedScopes = context.selectedIssuer.scopes_supported;
- } else {
- supportedScopes = [context.selectedCredentialType['scope']];
- }
return await authorize(
constructAuthorizationConfiguration(
context.selectedIssuer,
- supportedScopes,
+ context.selectedCredentialType.scope,
),
);
},
@@ -118,21 +107,19 @@ export const IssuersService = () => {
},
verifyCredential: async (context: any) => {
//this issuer specific check has to be removed once vc validation is done.
- if (
- VCMetadata.fromVcMetadataString(getVCMetadata(context)).issuer ===
- Issuers.Sunbird
- ) {
+ if (isMosipVC(context.vcMetadata.issuer)) {
+ const verificationResult = await verifyCredential(
+ context.verifiableCredential?.credential,
+ );
+ if (!verificationResult.isVerified) {
+ throw new Error(verificationResult.errorMessage);
+ }
+ } else {
return {
isVerified: true,
errorMessage: VerificationErrorType.NO_ERROR,
};
}
- const verificationResult = await verifyCredential(
- context.verifiableCredential?.credential,
- );
- if (!verificationResult.isVerified) {
- throw new Error(verificationResult.errorMessage);
- }
},
};
};
diff --git a/machines/QrLogin/QrLoginSelectors.ts b/machines/QrLogin/QrLoginSelectors.ts
index 2d65d57b..bc6e7056 100644
--- a/machines/QrLogin/QrLoginSelectors.ts
+++ b/machines/QrLogin/QrLoginSelectors.ts
@@ -2,6 +2,7 @@ import {StateFrom} from 'xstate';
import {getMosipLogo} from '../../components/VC/common/VCUtils';
import {VCMetadata} from '../../shared/VCMetadata';
import {qrLoginMachine} from './QrLoginMachine';
+import {Credential} from '../VerifiableCredential/VCMetaMachine/vc';
type State = StateFrom;
@@ -57,31 +58,29 @@ export function selectIsVerifyingSuccesful(state: State) {
return state.matches('success');
}
-export function selectCredential(state: State) {
- return new VCMetadata(state.context.selectedVc?.vcMetadata).isFromOpenId4VCI()
- ? state.context.selectedVc?.verifiableCredential?.credential
- : state.context.selectedVc?.credential;
+export function selectCredential(state: State): Credential {
+ return (
+ state.context.selectedVc?.verifiableCredential?.credential ||
+ state.context.selectedVc?.credential
+ );
}
export function selectVerifiableCredentialData(state: State) {
const vcMetadata = new VCMetadata(state.context.selectedVc?.vcMetadata);
- return vcMetadata.isFromOpenId4VCI()
- ? {
- vcMetadata: vcMetadata,
- face: state.context.selectedVc?.verifiableCredential?.credential
- ?.credentialSubject?.face,
- issuerLogo: state.context.selectedVc?.verifiableCredential?.issuerLogo,
- wellKnown: state.context.selectedVc?.verifiableCredential?.wellKnown,
- credentialTypes:
- state.context.selectedVc?.verifiableCredential?.credentialTypes,
- issuer: vcMetadata.issuer,
- }
- : {
- vcMetadata: vcMetadata,
- issuer: vcMetadata.issuer,
- face: state.context.selectedVc?.credential?.biometrics?.face,
- issuerLogo: getMosipLogo(),
- };
+ return {
+ vcMetadata: vcMetadata,
+ issuer: vcMetadata.issuer,
+ issuerLogo:
+ state.context.selectedVc?.verifiableCredential?.issuerLogo ||
+ getMosipLogo(),
+ face:
+ state.context.selectedVc?.verifiableCredential?.credential
+ ?.credentialSubject?.face ||
+ state.context.selectedVc?.credential?.biometrics?.face,
+ wellKnown: state.context.selectedVc?.verifiableCredential?.wellKnown,
+ credentialTypes:
+ state.context.selectedVc?.verifiableCredential?.credentialTypes,
+ };
}
export function selectLinkTransactionResponse(state: State) {
diff --git a/machines/VerifiableCredential/VCItemMachine/VCItemActions.ts b/machines/VerifiableCredential/VCItemMachine/VCItemActions.ts
index 6e473378..d82a0d8f 100644
--- a/machines/VerifiableCredential/VCItemMachine/VCItemActions.ts
+++ b/machines/VerifiableCredential/VCItemMachine/VCItemActions.ts
@@ -2,17 +2,18 @@ import {assign, send} from 'xstate';
import {CommunicationDetails} from '../../../shared/Utils';
import {StoreEvents} from '../../store';
import {VCMetadata} from '../../../shared/VCMetadata';
-import {MIMOTO_BASE_URL, MY_VCS_STORE_KEY} from '../../../shared/constants';
+import {
+ API_CACHED_STORAGE_KEYS,
+ MIMOTO_BASE_URL,
+ MY_VCS_STORE_KEY,
+} from '../../../shared/constants';
import {KeyPair} from 'react-native-rsa-native';
import i18n from '../../../i18n';
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,
- getVcVerificationDetails,
-} from '../../../shared/openId4VCI/Utils';
+import {getVcVerificationDetails} from '../../../shared/openId4VCI/Utils';
import {TelemetryConstants} from '../../../shared/telemetry/TelemetryConstants';
import {
sendStartEvent,
@@ -30,6 +31,7 @@ import {BackupEvents} from '../../backupAndRestore/backup';
import {VcMetaEvents} from '../VCMetaMachine/VCMetaMachine';
import {WalletBindingResponse} from '../VCMetaMachine/vc';
import {BannerStatusType} from '../../../components/BannerNotification';
+import {getCredentialTypes} from '../../../components/VC/common/VCUtils';
export const VCItemActions = model => {
return {
@@ -61,6 +63,7 @@ export const VCItemActions = model => {
statusType,
context.vcMetadata,
context.verifiableCredential,
+ context.wellknownResponse,
);
},
}),
@@ -124,10 +127,11 @@ export const VCItemActions = model => {
),
setContext: model.assign((context, event) => {
+ const vcMetadata = context.vcMetadata;
return {
...context,
...event.response,
- vcMetadata: context.vcMetadata,
+ vcMetadata: VCMetadata.fromVC(vcMetadata),
};
}),
storeContext: send(
@@ -149,16 +153,22 @@ export const VCItemActions = model => {
to: context => context.serviceRefs.store,
},
),
+
setVcMetadata: assign({
vcMetadata: (_, event) => event.vcMetadata,
}),
+
+ updateWellknownResponse: assign({
+ wellknownResponse: (_, event) => event.data,
+ }),
+
storeVcInContext: send(
//todo : separate handling done for openid4vci , handle commonly from vc machine
(context: any) => {
- const {serviceRefs, ...verifiableCredential} = context;
+ const {serviceRefs, wellknownResponse, ...data} = context;
return {
type: 'VC_DOWNLOADED',
- vc: verifiableCredential,
+ vc: data,
vcMetadata: context.vcMetadata,
};
},
@@ -442,7 +452,8 @@ export const VCItemActions = model => {
_vcKey: context.vcMetadata.getVcKey(),
type: 'VC_DOWNLOADED',
id: context.vcMetadata.id,
- idType: getIdType(context.vcMetadata.issuer),
+ issuer: context.vcMetadata.issuer!!,
+ idType: getCredentialTypes(context.verifiableCredential),
timestamp: Date.now(),
deviceName: '',
vcLabel: data.id,
@@ -453,47 +464,56 @@ export const VCItemActions = model => {
},
),
logRemovedVc: send(
- (context: any, _) =>
- ActivityLogEvents.LOG_ACTIVITY({
- idType: getIdType(context.vcMetadata.issuer),
- id: context.vcMetadata.id,
- _vcKey: VCMetadata.fromVC(context.vcMetadata).getVcKey(),
+ (context: any, _) => {
+ const vcMetadata = VCMetadata.fromVC(context.vcMetadata);
+ return ActivityLogEvents.LOG_ACTIVITY({
+ idType: getCredentialTypes(context.verifiableCredential),
+ issuer: vcMetadata.issuer!!,
+ id: vcMetadata.id,
+ _vcKey: vcMetadata.getVcKey(),
type: 'VC_REMOVED',
timestamp: Date.now(),
deviceName: '',
- vcLabel: VCMetadata.fromVC(context.vcMetadata).id,
- }),
+ vcLabel: vcMetadata.id,
+ });
+ },
{
to: context => context.serviceRefs.activityLog,
},
),
logWalletBindingSuccess: send(
- (context: any) =>
- ActivityLogEvents.LOG_ACTIVITY({
- _vcKey: VCMetadata.fromVC(context.vcMetadata).getVcKey(),
+ (context: any) => {
+ const vcMetadata = VCMetadata.fromVC(context.vcMetadata);
+ return ActivityLogEvents.LOG_ACTIVITY({
+ _vcKey: vcMetadata.getVcKey(),
type: 'WALLET_BINDING_SUCCESSFULL',
- idType: getIdType(context.vcMetadata.issuer),
- id: context.vcMetadata.id,
+ idType: getCredentialTypes(context.verifiableCredential),
+ issuer: vcMetadata.issuer!!,
+ id: vcMetadata.id,
timestamp: Date.now(),
deviceName: '',
- vcLabel: VCMetadata.fromVC(context.vcMetadata).id,
- }),
+ vcLabel: vcMetadata.id,
+ });
+ },
{
to: context => context.serviceRefs.activityLog,
},
),
logWalletBindingFailure: send(
- (context: any) =>
- ActivityLogEvents.LOG_ACTIVITY({
- _vcKey: VCMetadata.fromVC(context.vcMetadata).getVcKey(),
+ (context: any) => {
+ const vcMetadata = VCMetadata.fromVC(context.vcMetadata);
+ return ActivityLogEvents.LOG_ACTIVITY({
+ _vcKey: vcMetadata.getVcKey(),
type: 'WALLET_BINDING_FAILURE',
- id: context.vcMetadata.id,
- idType: getIdType(context.vcMetadata.issuer),
+ id: vcMetadata.id,
+ idType: getCredentialTypes(context.verifiableCredential),
+ issuer: vcMetadata.issuer!!,
timestamp: Date.now(),
deviceName: '',
- vcLabel: VCMetadata.fromVC(context.vcMetadata).id,
- }),
+ vcLabel: vcMetadata.id,
+ });
+ },
{
to: context => context.serviceRefs.activityLog,
},
diff --git a/machines/VerifiableCredential/VCItemMachine/VCItemEvents.ts b/machines/VerifiableCredential/VCItemMachine/VCItemEvents.ts
deleted file mode 100644
index d14585f6..00000000
--- a/machines/VerifiableCredential/VCItemMachine/VCItemEvents.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import {VCMetadata} from '../../../shared/VCMetadata';
-import {VC} from '../VCMetaMachine/vc';
-
-export const VCItemEvents = {
- DISMISS: () => ({}),
- CREDENTIAL_DOWNLOADED: (response: VC) => ({response}),
- STORE_RESPONSE: (response: VC) => ({response}),
- STORE_ERROR: (error: Error) => ({error}),
- POLL: () => ({}),
- DOWNLOAD_READY: () => ({}),
- FAILED: () => ({}),
- GET_VC_RESPONSE: (response: VC) => ({response}),
- INPUT_OTP: (OTP: string) => ({OTP}),
- RESEND_OTP: () => ({}),
- REFRESH: () => ({}),
- ADD_WALLET_BINDING_ID: () => ({}),
- CANCEL: () => ({}),
- CONFIRM: () => ({}),
- PIN_CARD: () => ({}),
- KEBAB_POPUP: () => ({}),
- SHOW_ACTIVITY: () => ({}),
- CLOSE_VC_MODAL: () => ({}),
- REMOVE: (vcMetadata: VCMetadata) => ({vcMetadata}),
- 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}),
-};
diff --git a/machines/VerifiableCredential/VCItemMachine/VCItemGaurds.ts b/machines/VerifiableCredential/VCItemMachine/VCItemGaurds.ts
index 544de8cb..d8bb64c0 100644
--- a/machines/VerifiableCredential/VCItemMachine/VCItemGaurds.ts
+++ b/machines/VerifiableCredential/VCItemMachine/VCItemGaurds.ts
@@ -4,9 +4,16 @@ import {VerificationErrorType} from '../../../shared/vcjs/verifyCredential';
export const VCItemGaurds = () => {
return {
+ hasCredentialAndWellknown: (context, event) => {
+ const vc = event.response;
+ return (
+ vc?.verifiableCredential != null &&
+ !!context.verifiableCredential?.wellKnown
+ );
+ },
hasCredential: (_, event) => {
const vc = event.response;
- return vc?.credential != null || vc?.verifiableCredential != null;
+ return vc?.verifiableCredential != null;
},
isSignedIn: (_context, event) =>
(event.data as isSignedInResult).isSignedIn,
diff --git a/machines/VerifiableCredential/VCItemMachine/VCItemMachine.ts b/machines/VerifiableCredential/VCItemMachine/VCItemMachine.ts
index 24dc2b8a..74568f5c 100644
--- a/machines/VerifiableCredential/VCItemMachine/VCItemMachine.ts
+++ b/machines/VerifiableCredential/VCItemMachine/VCItemMachine.ts
@@ -44,6 +44,11 @@ export const VCItemMachine = model.createMachine(
description: 'Fetch the VC data from the Memory.',
on: {
GET_VC_RESPONSE: [
+ {
+ actions: ['setContext'],
+ cond: 'hasCredentialAndWellknown',
+ target: '.fetchWellknown',
+ },
{
actions: ['setContext'],
cond: 'hasCredential',
@@ -58,6 +63,20 @@ export const VCItemMachine = model.createMachine(
target: '#vc-item-machine.vcUtilitiesState.idle',
},
},
+ initial: 'idle',
+ states: {
+ idle: {},
+ fetchWellknown: {
+ invoke: {
+ src: 'fetchIssuerWellknown',
+ onDone: {
+ actions: 'updateWellknownResponse',
+
+ target: `#vc-item-machine.vcUtilitiesState.idle`,
+ },
+ },
+ },
+ },
},
loadVcFromServer: {
description:
@@ -492,10 +511,10 @@ export const VCItemMachine = model.createMachine(
{
cond: 'isSignedIn',
actions: ['sendBackupEvent'],
- target: '#vc-item-machine.vcUtilitiesState.idle',
+ target: `#vc-item-machine.vcUtilitiesState.idle`,
},
{
- target: '#vc-item-machine.vcUtilitiesState.idle',
+ target: `#vc-item-machine.vcUtilitiesState.idle`,
},
],
},
diff --git a/machines/VerifiableCredential/VCItemMachine/VCItemMachine.typegen.ts b/machines/VerifiableCredential/VCItemMachine/VCItemMachine.typegen.ts
index 08d33f69..e0e4de88 100644
--- a/machines/VerifiableCredential/VCItemMachine/VCItemMachine.typegen.ts
+++ b/machines/VerifiableCredential/VCItemMachine/VCItemMachine.typegen.ts
@@ -19,6 +19,11 @@ export interface Typegen0 {
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
+ 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromContext.fetchWellknown:invocation[0]': {
+ type: 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromContext.fetchWellknown: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;
@@ -120,6 +125,7 @@ export interface Typegen0 {
checkDownloadExpiryLimit: 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromServer.verifyingDownloadLimitExpiry:invocation[0]';
checkStatus: 'done.invoke.checkStatus';
downloadCredential: 'done.invoke.downloadCredential';
+ fetchIssuerWellknown: 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromContext.fetchWellknown:invocation[0]';
generateKeyPair: 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]';
isUserSignedAlready:
| 'done.invoke.vc-item-machine.vcUtilitiesState.kebabPopUp.triggerAutoBackup:invocation[0]'
@@ -186,10 +192,12 @@ export interface Typegen0 {
| 'unSetBindingTransactionId'
| 'unSetError'
| 'unSetOTP'
- | 'updateVcMetadata';
+ | 'updateVcMetadata'
+ | 'updateWellknownResponse';
delays: never;
guards:
| 'hasCredential'
+ | 'hasCredentialAndWellknown'
| 'isCustomSecureKeystore'
| 'isDownloadAllowed'
| 'isSignedIn'
@@ -199,6 +207,7 @@ export interface Typegen0 {
| 'checkDownloadExpiryLimit'
| 'checkStatus'
| 'downloadCredential'
+ | 'fetchIssuerWellknown'
| 'generateKeyPair'
| 'isUserSignedAlready'
| 'loadDownloadLimitConfig'
@@ -334,10 +343,12 @@ export interface Typegen0 {
| 'DISMISS'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.requestingBindingOTP:invocation[0]';
updateVcMetadata: 'PIN_CARD' | 'STORE_RESPONSE';
+ updateWellknownResponse: 'done.invoke.vc-item-machine.vcUtilitiesState.loadVc.loadVcFromContext.fetchWellknown:invocation[0]';
};
eventsCausingDelays: {};
eventsCausingGuards: {
hasCredential: 'GET_VC_RESPONSE';
+ hasCredentialAndWellknown: 'GET_VC_RESPONSE';
isCustomSecureKeystore:
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addKeyPair:invocation[0]'
| 'done.invoke.vc-item-machine.vcUtilitiesState.walletBinding.addingWalletBindingId:invocation[0]';
@@ -356,6 +367,7 @@ export interface Typegen0 {
| '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';
+ fetchIssuerWellknown: 'GET_VC_RESPONSE';
generateKeyPair: 'INPUT_OTP';
isUserSignedAlready: 'STORE_RESPONSE';
loadDownloadLimitConfig: 'GET_VC_RESPONSE' | 'STORE_ERROR';
@@ -375,6 +387,8 @@ export interface Typegen0 {
| 'vcUtilitiesState.kebabPopUp.triggerAutoBackup'
| 'vcUtilitiesState.loadVc'
| 'vcUtilitiesState.loadVc.loadVcFromContext'
+ | 'vcUtilitiesState.loadVc.loadVcFromContext.fetchWellknown'
+ | 'vcUtilitiesState.loadVc.loadVcFromContext.idle'
| 'vcUtilitiesState.loadVc.loadVcFromServer'
| 'vcUtilitiesState.loadVc.loadVcFromServer.checkingStatus'
| 'vcUtilitiesState.loadVc.loadVcFromServer.downloadingCredential'
@@ -421,6 +435,7 @@ export interface Typegen0 {
| 'loadVcFromContext'
| 'loadVcFromServer'
| {
+ loadVcFromContext?: 'fetchWellknown' | 'idle';
loadVcFromServer?:
| 'checkingStatus'
| 'downloadingCredential'
diff --git a/machines/VerifiableCredential/VCItemMachine/VCItemModel.ts b/machines/VerifiableCredential/VCItemMachine/VCItemModel.ts
index b1c62cc1..74e3015a 100644
--- a/machines/VerifiableCredential/VCItemMachine/VCItemModel.ts
+++ b/machines/VerifiableCredential/VCItemMachine/VCItemModel.ts
@@ -1,17 +1,52 @@
import {createModel} from 'xstate/lib/model';
import {AppServices} from '../../../shared/GlobalContext';
import {VCMetadata} from '../../../shared/VCMetadata';
-import {VerifiableCredential, WalletBindingResponse} from '../VCMetaMachine/vc';
+import {
+ Credential,
+ DecodedCredential,
+ VC,
+ WalletBindingResponse,
+} from '../VCMetaMachine/vc';
import {CommunicationDetails} from '../../../shared/Utils';
-import {VCItemEvents} from './VCItemEvents';
import {vcVerificationBannerDetails} from '../../../components/BannerNotificationContainer';
+const VCItemEvents = {
+ DISMISS: () => ({}),
+ CREDENTIAL_DOWNLOADED: (response: VC) => ({response}),
+ STORE_RESPONSE: (response: VC) => ({response}),
+ STORE_ERROR: (error: Error) => ({error}),
+ POLL: () => ({}),
+ DOWNLOAD_READY: () => ({}),
+ FAILED: () => ({}),
+ GET_VC_RESPONSE: (response: VC) => ({response}),
+ INPUT_OTP: (OTP: string) => ({OTP}),
+ RESEND_OTP: () => ({}),
+ REFRESH: () => ({}),
+ ADD_WALLET_BINDING_ID: () => ({}),
+ CANCEL: () => ({}),
+ CONFIRM: () => ({}),
+ PIN_CARD: () => ({}),
+ KEBAB_POPUP: () => ({}),
+ SHOW_ACTIVITY: () => ({}),
+ CLOSE_VC_MODAL: () => ({}),
+ REMOVE: (vcMetadata: VCMetadata) => ({vcMetadata}),
+ 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}),
+};
+
export const VCItemModel = createModel(
{
serviceRefs: {} as AppServices,
vcMetadata: {} as VCMetadata,
generatedOn: new Date() as Date,
- verifiableCredential: null as unknown as VerifiableCredential,
+ credential: null as unknown as DecodedCredential,
+ verifiableCredential: null as unknown as Credential,
hashedId: '',
publicKey: '',
privateKey: '',
@@ -27,6 +62,7 @@ export const VCItemModel = createModel(
communicationDetails: null as unknown as CommunicationDetails,
verificationStatus: null as vcVerificationBannerDetails | null,
showVerificationStatusBanner: false as boolean,
+ wellknownResponse: {} as Object,
},
{
events: VCItemEvents,
diff --git a/machines/VerifiableCredential/VCItemMachine/VCItemSelectors.ts b/machines/VerifiableCredential/VCItemMachine/VCItemSelectors.ts
index bcb254ca..d52091cb 100644
--- a/machines/VerifiableCredential/VCItemMachine/VCItemSelectors.ts
+++ b/machines/VerifiableCredential/VCItemMachine/VCItemSelectors.ts
@@ -2,6 +2,11 @@ import {StateFrom} from 'xstate';
import {VCMetadata} from '../../../shared/VCMetadata';
import {VCItemMachine} from './VCItemMachine';
import {getMosipLogo} from '../../../components/VC/common/VCUtils';
+import {
+ Credential,
+ VerifiableCredential,
+ VerifiableCredentialData,
+} from '../VCMetaMachine/vc';
type State = StateFrom;
@@ -26,39 +31,31 @@ export function selectVerifiableCredential(state: State) {
}
export function getVerifiableCredential(
- vcMetadata: VCMetadata,
- verifiableCredential,
-) {
- return VCMetadata.fromVC(vcMetadata).isFromOpenId4VCI()
- ? verifiableCredential?.credential
- : verifiableCredential;
+ verifiableCredential: VerifiableCredential | Credential,
+): Credential {
+ return verifiableCredential?.credential || verifiableCredential;
}
-export function selectCredential(state: State) {
- return getVerifiableCredential(
- state.context.vcMetadata,
- state.context.verifiableCredential,
- );
+export function selectCredential(state: State): Credential {
+ return getVerifiableCredential(state.context.verifiableCredential);
}
-export function selectVerifiableCredentialData(state: State) {
+export function selectVerifiableCredentialData(
+ state: State,
+): VerifiableCredentialData {
const vcMetadata = new VCMetadata(state.context.vcMetadata);
- return vcMetadata.isFromOpenId4VCI()
- ? {
- vcMetadata: vcMetadata,
- face: state.context.verifiableCredential?.credential?.credentialSubject
- .face,
- issuerLogo: state.context.verifiableCredential?.issuerLogo,
- wellKnown: state.context.verifiableCredential?.wellKnown,
- credentialTypes: state.context.verifiableCredential?.credentialTypes,
- issuer: vcMetadata.issuer,
- }
- : {
- vcMetadata: vcMetadata,
- issuer: vcMetadata.issuer,
- face: state.context.credential?.biometrics?.face,
- issuerLogo: getMosipLogo(),
- };
+
+ return {
+ vcMetadata: vcMetadata,
+ face:
+ state.context.verifiableCredential?.credential?.credentialSubject?.face ??
+ state.context.credential?.biometrics?.face,
+ issuerLogo:
+ state.context.verifiableCredential?.issuerLogo ?? getMosipLogo(),
+ wellKnown: state.context.verifiableCredential?.wellKnown,
+ credentialTypes: state.context.verifiableCredential?.credentialTypes,
+ issuer: vcMetadata.issuer,
+ };
}
export function selectKebabPopUp(state: State) {
diff --git a/machines/VerifiableCredential/VCItemMachine/VCItemServices.ts b/machines/VerifiableCredential/VCItemMachine/VCItemServices.ts
index ac1872b3..aaab00d9 100644
--- a/machines/VerifiableCredential/VCItemMachine/VCItemServices.ts
+++ b/machines/VerifiableCredential/VCItemMachine/VCItemServices.ts
@@ -3,6 +3,7 @@ import Cloud from '../../../shared/CloudBackupAndRestoreUtils';
import {VCMetadata} from '../../../shared/VCMetadata';
import getAllConfigurations, {
API_URLS,
+ CACHED_API,
DownloadProps,
} from '../../../shared/api';
import {
@@ -16,8 +17,9 @@ import {
import {CredentialDownloadResponse, request} from '../../../shared/request';
import {WalletBindingResponse} from '../VCMetaMachine/vc';
import {verifyCredential} from '../../../shared/vcjs/verifyCredential';
-import {getMosipIdentifier} from '../../../shared/commonUtil';
import {getVerifiableCredential} from './VCItemSelectors';
+import {getSelectedCredentialTypeDetails} from '../../../shared/openId4VCI/Utils';
+import {getCredentialTypes} from '../../../components/VC/common/VCUtils';
const {RNSecureKeystoreModule} = NativeModules;
export const VCItemServices = model => {
@@ -105,9 +107,7 @@ export const VCItemServices = model => {
);
},
requestBindingOTP: async context => {
- const vc = VCMetadata.fromVC(context.vcMetadata).isFromOpenId4VCI()
- ? context.verifiableCredential.credential
- : context.verifiableCredential;
+ const vc = getVerifiableCredential(context.verifiableCredential);
const response = await request(
API_URLS.bindingOtp.method,
API_URLS.bindingOtp.buildURL(),
@@ -124,6 +124,18 @@ export const VCItemServices = model => {
}
return response;
},
+ fetchIssuerWellknown: async context => {
+ const wellknownResponse = await CACHED_API.fetchIssuerWellknownConfig(
+ context.vcMetadata.issuer,
+ context.verifiableCredential.wellKnown,
+ true,
+ );
+ const wellknownOfCredential = getSelectedCredentialTypeDetails(
+ wellknownResponse,
+ getCredentialTypes(context.verifiableCredential),
+ );
+ return wellknownOfCredential;
+ },
checkStatus: context => (callback, onReceive) => {
const pollInterval = setInterval(
() => callback(model.events.POLL()),
@@ -199,10 +211,7 @@ export const VCItemServices = model => {
verifyCredential: async context => {
if (context.verifiableCredential) {
const verificationResult = await verifyCredential(
- getVerifiableCredential(
- context.vcMetadata,
- context.verifiableCredential,
- ),
+ getVerifiableCredential(context.verifiableCredential),
);
if (!verificationResult.isVerified) {
throw new Error(verificationResult.errorMessage);
diff --git a/machines/VerifiableCredential/VCMetaMachine/VCMetaSelectors.ts b/machines/VerifiableCredential/VCMetaMachine/VCMetaSelectors.ts
index 945c3079..7896a3ab 100644
--- a/machines/VerifiableCredential/VCMetaMachine/VCMetaSelectors.ts
+++ b/machines/VerifiableCredential/VCMetaMachine/VCMetaSelectors.ts
@@ -15,7 +15,6 @@ export function selectMyVcsMetadata(state: State): VCMetadata[] {
export function selectShareableVcsMetadata(state: State): VCMetadata[] {
return state.context.myVcsMetadata.filter(
vcMetadata =>
- state.context.myVcs[vcMetadata.getVcKey()]?.credential != null ||
state.context.myVcs[vcMetadata.getVcKey()]?.verifiableCredential != null,
);
}
diff --git a/machines/VerifiableCredential/VCMetaMachine/vc.d.ts b/machines/VerifiableCredential/VCMetaMachine/vc.d.ts
index 572aed39..de01a52f 100644
--- a/machines/VerifiableCredential/VCMetaMachine/vc.d.ts
+++ b/machines/VerifiableCredential/VCMetaMachine/vc.d.ts
@@ -1,15 +1,17 @@
import {displayType, logoType} from '../../Issuers/IssuersMachine';
+import {VCMetadata} from '../../../shared/VCMetadata';
export interface VC {
id?: string;
idType?: VcIdType;
credential?: DecodedCredential;
- verifiableCredential: VerifiableCredential;
+ verifiableCredential: VerifiableCredential | Credential;
requestId?: string;
isVerified?: boolean;
lastVerifiedOn: number;
walletBindingResponse?: WalletBindingResponse;
hashedId?: string;
+ vcMetadata: VCMetadata;
}
export type VcIdType = 'UIN' | 'VID';
@@ -54,7 +56,8 @@ export interface Credential {
type: 'RsaSignature2018' | string;
verificationMethod: string;
};
- type: VerifiableCredentialType[];
+ type: string[];
+ credentialTypes: string[];
}
export interface VerifiableCredential {
@@ -65,11 +68,20 @@ export interface VerifiableCredential {
credentialTypes: Object[];
}
+export interface VerifiableCredentialData {
+ vcMetadata: VCMetadata;
+ face: string;
+ issuerLogo: logoType;
+ wellKnown?: string;
+ credentialTypes?: Object[];
+ issuer?: string;
+}
+
export interface CredentialWrapper {
verifiableCredential: VerifiableCredential;
identifier: string;
generatedOn: Date;
- issuerLogo: string;
+ vcMetadata: VCMetadata;
}
export interface CredentialTypes {
@@ -84,10 +96,11 @@ export interface CredentialTypes {
};
}
-export type VerifiableCredentialType =
- | 'VerifiableCredential'
- | 'MOSIPVerfiableCredential'
- | string;
+export interface IssuerWellknownResponse {
+ credential_issuer: string;
+ credential_endpoint: string;
+ credentials_supported: Object[];
+}
export interface VCLabel {
singular: string;
@@ -116,3 +129,16 @@ export interface WalletBindingResponse {
thumbprint: string;
expireDateTime: string;
}
+
+//TODO: Check if Type word is needed in the naming
+export interface VCMetadataType {
+ //TODO: requestId is not null at any point as its used for file names and all
+ isPinned: boolean;
+ requestId: string | null;
+ issuer: string;
+ protocol: string;
+ id: string;
+ timestamp: string;
+ isVerified: boolean;
+ credentialType: string;
+}
diff --git a/machines/activityLog.ts b/machines/activityLog.ts
index 0ea74c2e..bad9ddad 100644
--- a/machines/activityLog.ts
+++ b/machines/activityLog.ts
@@ -9,11 +9,15 @@ const model = createModel(
{
serviceRefs: {} as AppServices,
activities: [] as ActivityLog[],
+ wellKnownIssuerMap: {} as Record,
},
{
events: {
STORE_RESPONSE: (response: unknown) => ({response}),
- LOG_ACTIVITY: (log: ActivityLog | ActivityLog[]) => ({log}),
+ LOG_ACTIVITY: (log: ActivityLog | ActivityLog[], wellknown?: any) => ({
+ log,
+ wellknown,
+ }),
REFRESH: () => ({}),
},
},
@@ -40,6 +44,15 @@ export const activityLogMachine =
on: {
STORE_RESPONSE: {
actions: ['setActivities', sendParent('READY')],
+ target: 'loadWellknownConfig',
+ },
+ },
+ },
+ loadWellknownConfig: {
+ entry: 'fetchAllWellKnownConfigResponse',
+ on: {
+ STORE_RESPONSE: {
+ actions: ['setAllWellknownConfigResponse'],
target: 'ready',
},
},
@@ -58,7 +71,7 @@ export const activityLogMachine =
},
},
logging: {
- entry: 'storeActivity',
+ entry: ['loadWellknownIntoContext', 'storeActivity'],
on: {
STORE_RESPONSE: {
actions: 'prependActivity',
@@ -94,11 +107,41 @@ export const activityLogMachine =
{to: context => context.serviceRefs.store},
),
+ loadWellknownIntoContext: model.assign({
+ wellKnownIssuerMap: (context, event) => {
+ if (!!event.wellknown) {
+ const updatedWellKnownIssuerMap = {
+ ...context.wellKnownIssuerMap,
+ };
+ updatedWellKnownIssuerMap[event.log.issuer] = event.wellknown;
+ return updatedWellKnownIssuerMap as unknown as Record<
+ string,
+ Object
+ >;
+ }
+ return context.wellKnownIssuerMap;
+ },
+ }),
+
prependActivity: model.assign({
- activities: (context, event) =>
- (Array.isArray(event.response)
- ? [...event.response, ...context.activities]
- : [event.response, ...context.activities]) as ActivityLog[],
+ activities: (context, event) => {
+ return (
+ Array.isArray(event.response)
+ ? [...event.response, ...context.activities]
+ : [event.response, ...context.activities]
+ ) as ActivityLog[];
+ },
+ }),
+
+ fetchAllWellKnownConfigResponse: send(
+ () => StoreEvents.FETCH_ALL_WELLKNOWN_CONFIG(),
+ {to: context => context.serviceRefs.store},
+ ),
+
+ setAllWellknownConfigResponse: model.assign({
+ wellKnownIssuerMap: (_, event) => {
+ return event.response as Record;
+ },
}),
},
},
@@ -134,6 +177,10 @@ export function selectActivities(state: State) {
return state.context.activities;
}
+export function selectWellknownIssuerMap(state: State) {
+ return state.context.wellKnownIssuerMap;
+}
+
export function selectIsRefreshing(state: State) {
return state.matches('ready.refreshing');
}
diff --git a/machines/activityLog.typegen.ts b/machines/activityLog.typegen.ts
index ff117107..24cedabf 100644
--- a/machines/activityLog.typegen.ts
+++ b/machines/activityLog.typegen.ts
@@ -1,36 +1,36 @@
+// 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: {
- "xstate.init": { type: "xstate.init" };
- };
- invokeSrcNameMap: {
-
- };
- missingImplementations: {
- actions: never;
- delays: never;
- guards: never;
- services: never;
- };
- eventsCausingActions: {
- "loadActivities": "REFRESH" | "xstate.init";
-"prependActivity": "STORE_RESPONSE";
-"setActivities": "STORE_RESPONSE";
-"storeActivity": "LOG_ACTIVITY";
- };
- eventsCausingDelays: {
-
- };
- eventsCausingGuards: {
-
- };
- eventsCausingServices: {
-
- };
- matchesStates: "init" | "ready" | "ready.idle" | "ready.logging" | "ready.refreshing" | { "ready"?: "idle" | "logging" | "refreshing"; };
- tags: never;
- }
-
\ No newline at end of file
+export interface Typegen0 {
+ '@@xstate/typegen': true;
+ internalEvents: {
+ 'xstate.init': {type: 'xstate.init'};
+ };
+ invokeSrcNameMap: {};
+ missingImplementations: {
+ actions: never;
+ delays: never;
+ guards: never;
+ services: never;
+ };
+ eventsCausingActions: {
+ fetchAllWellKnownConfigResponse: 'STORE_RESPONSE';
+ loadActivities: 'REFRESH' | 'xstate.init';
+ loadWellknownIntoContext: 'LOG_ACTIVITY';
+ prependActivity: 'STORE_RESPONSE';
+ setActivities: 'STORE_RESPONSE';
+ setAllWellknownConfigResponse: 'STORE_RESPONSE';
+ storeActivity: 'LOG_ACTIVITY';
+ };
+ eventsCausingDelays: {};
+ eventsCausingGuards: {};
+ eventsCausingServices: {};
+ matchesStates:
+ | 'init'
+ | 'loadWellknownConfig'
+ | 'ready'
+ | 'ready.idle'
+ | 'ready.logging'
+ | 'ready.refreshing'
+ | {ready?: 'idle' | 'logging' | 'refreshing'};
+ tags: never;
+}
diff --git a/machines/bleShare/request/requestMachine.ts b/machines/bleShare/request/requestMachine.ts
index 8d64dfa7..5385a74c 100644
--- a/machines/bleShare/request/requestMachine.ts
+++ b/machines/bleShare/request/requestMachine.ts
@@ -37,7 +37,7 @@ import {
sendStartEvent,
} from '../../../shared/telemetry/TelemetryUtils';
import {TelemetryConstants} from '../../../shared/telemetry/TelemetryConstants';
-import {getIdType} from '../../../shared/openId4VCI/Utils';
+import {getCredentialTypes} from '../../../components/VC/common/VCUtils';
const {verifier, EventTypes, VerificationStatus} = tuvali;
@@ -620,7 +620,10 @@ export const requestMachine =
_vcKey: vcMetadata.getVcKey(),
type: context.receiveLogType,
id: vcMetadata.id,
- idType: getIdType(vcMetadata.issuer),
+ idType: getCredentialTypes(
+ context.incomingVc.verifiableCredential,
+ ),
+ issuer: vcMetadata.issuer!!,
timestamp: Date.now(),
deviceName:
context.senderInfo.name || context.senderInfo.deviceName,
diff --git a/machines/bleShare/request/selectors.ts b/machines/bleShare/request/selectors.ts
index 7b670ac1..308e2283 100644
--- a/machines/bleShare/request/selectors.ts
+++ b/machines/bleShare/request/selectors.ts
@@ -2,6 +2,7 @@ import {StateFrom} from 'xstate';
import {requestMachine} from './requestMachine';
import {VCMetadata} from '../../../shared/VCMetadata';
import {getMosipLogo} from '../../../components/VC/common/VCUtils';
+import {Credential} from '../../VerifiableCredential/VCMetaMachine/vc';
type State = StateFrom;
@@ -9,31 +10,29 @@ export function selectSenderInfo(state: State) {
return state.context.senderInfo;
}
-export function selectCredential(state: State) {
- return new VCMetadata(state.context.incomingVc?.vcMetadata).isFromOpenId4VCI()
- ? state.context.incomingVc?.verifiableCredential?.credential
- : state.context.incomingVc?.verifiableCredential;
+export function selectCredential(state: State): Credential {
+ return (
+ state.context.incomingVc?.verifiableCredential?.credential ||
+ state.context.incomingVc?.verifiableCredential
+ );
}
export function selectVerifiableCredentialData(state: State) {
const vcMetadata = new VCMetadata(state.context.incomingVc?.vcMetadata);
- return vcMetadata.isFromOpenId4VCI()
- ? {
- vcMetadata: vcMetadata,
- face: state.context.incomingVc?.verifiableCredential.credential
- .credentialSubject.face,
- issuerLogo: state.context.incomingVc?.verifiableCredential?.issuerLogo,
- wellKnown: state.context.incomingVc?.verifiableCredential?.wellKnown,
- credentialTypes:
- state.context.incomingVc?.verifiableCredential?.credentialTypes,
- issuer: vcMetadata.issuer,
- }
- : {
- vcMetadata: vcMetadata,
- issuer: vcMetadata.issuer,
- face: state.context.incomingVc?.credential?.biometrics?.face,
- issuerLogo: getMosipLogo(),
- };
+ return {
+ vcMetadata: vcMetadata,
+ face:
+ state.context.incomingVc?.verifiableCredential.credential
+ ?.credentialSubject?.face ||
+ state.context.incomingVc?.credential?.biometrics?.face,
+ issuerLogo:
+ state.context.incomingVc?.verifiableCredential?.issuerLogo ||
+ getMosipLogo(),
+ issuer: vcMetadata.issuer,
+ wellKnown: state.context.incomingVc?.verifiableCredential?.wellKnown,
+ credentialTypes:
+ state.context.incomingVc?.verifiableCredential?.credentialTypes,
+ };
}
export function selectIsReviewingInIdle(state: State) {
diff --git a/machines/bleShare/scan/scanActions.ts b/machines/bleShare/scan/scanActions.ts
index 6aab8030..d08ee7f3 100644
--- a/machines/bleShare/scan/scanActions.ts
+++ b/machines/bleShare/scan/scanActions.ts
@@ -11,7 +11,6 @@ import {
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,
@@ -30,6 +29,7 @@ import {StoreEvents} from '../../store';
import tuvali from '@mosip/tuvali';
import BluetoothStateManager from 'react-native-bluetooth-state-manager';
import {NativeModules} from 'react-native';
+import {getCredentialTypes} from '../../../components/VC/common/VCUtils';
const {wallet, EventTypes, VerificationStatus} = tuvali;
export const ScanActions = (model: any, QR_LOGIN_REF_ID: any) => {
@@ -191,14 +191,16 @@ export const ScanActions = (model: any, QR_LOGIN_REF_ID: any) => {
logShared: send(
(context: any) => {
- const vcMetadata = context.selectedVc?.vcMetadata;
+ const vcMetadata = VCMetadata.fromVC(context.selectedVc?.vcMetadata);
+ const selectedVc = context.QrLoginRef.getSnapshot().context.selectedVc;
return ActivityLogEvents.LOG_ACTIVITY({
- _vcKey: VCMetadata.fromVC(vcMetadata).getVcKey(),
+ _vcKey: vcMetadata.getVcKey(),
type: context.shareLogType
? context.shareLogType
: 'VC_SHARED_WITH_VERIFICATION_CONSENT',
id: vcMetadata.id,
- idType: getIdType(vcMetadata.issuer),
+ idType: getCredentialTypes(selectedVc.verifiableCredential),
+ issuer: vcMetadata.issuer!!,
timestamp: Date.now(),
deviceName:
context.receiverInfo.name || context.receiverInfo.deviceName,
@@ -209,17 +211,21 @@ export const ScanActions = (model: any, QR_LOGIN_REF_ID: any) => {
),
logFailedVerification: send(
- context =>
- ActivityLogEvents.LOG_ACTIVITY({
- _vcKey: VCMetadata.fromVC(context.selectedVc).getVcKey(),
+ context => {
+ const vcMetadata = VCMetadata.fromVC(context.selectedVc);
+ const selectedVc = context.QrLoginRef.getSnapshot().context.selectedVc;
+ return ActivityLogEvents.LOG_ACTIVITY({
+ _vcKey: vcMetadata.getVcKey(),
type: 'PRESENCE_VERIFICATION_FAILED',
timestamp: Date.now(),
- idType: getIdType(context.selectedVc.vcMetadata.issuer),
- id: context.selectedVc.vcMetadata.id,
+ idType: getCredentialTypes(selectedVc.verifiableCredential),
+ id: vcMetadata.id,
+ issuer: vcMetadata.issuer!!,
deviceName:
context.receiverInfo.name || context.receiverInfo.deviceName,
- vcLabel: context.selectedVc.vcMetadata.id,
- }),
+ vcLabel: vcMetadata.id,
+ });
+ },
{to: context => context.serviceRefs.activityLog},
),
@@ -242,11 +248,8 @@ export const ScanActions = (model: any, QR_LOGIN_REF_ID: any) => {
),
loadVCDataToMemory: send(
(context: any) => {
- let metadata = VCMetadata.fromVC(context.quickShareData?.meta);
-
- let verifiableCredential = metadata.isFromOpenId4VCI()
- ? {credential: context.quickShareData?.verifiableCredential}
- : context.quickShareData?.verifiableCredential;
+ const verifiableCredential =
+ context.quickShareData?.verifiableCredential;
return StoreEvents.SET(metadata.getVcKey(), {
verifiableCredential: verifiableCredential,
@@ -268,16 +271,22 @@ export const ScanActions = (model: any, QR_LOGIN_REF_ID: any) => {
),
storingActivityLog: send(
- (_, event) =>
- ActivityLogEvents.LOG_ACTIVITY({
+ (context, event) => {
+ const vcMetadata = event.response.selectedVc.vcMetadata;
+
+ const selectedVc = context.QrLoginRef.getSnapshot().context.selectedVc;
+
+ return ActivityLogEvents.LOG_ACTIVITY({
_vcKey: '',
- id: event.response.selectedVc.vcMetadata.id,
- idType: getIdType(event.response.selectedVc.vcMetadata.issuer),
+ id: vcMetadata.id,
+ issuer: vcMetadata.issuer!!,
+ idType: getCredentialTypes(selectedVc.verifiableCredential),
type: 'QRLOGIN_SUCCESFULL',
timestamp: Date.now(),
deviceName: '',
- vcLabel: String(event.response.selectedVc.vcMetadata.id),
- }),
+ vcLabel: String(vcMetadata.id),
+ });
+ },
{
to: (context: any) => context.serviceRefs.activityLog,
},
diff --git a/machines/bleShare/scan/scanSelectors.ts b/machines/bleShare/scan/scanSelectors.ts
index a5159c41..64c77a00 100644
--- a/machines/bleShare/scan/scanSelectors.ts
+++ b/machines/bleShare/scan/scanSelectors.ts
@@ -18,30 +18,28 @@ export function selectVcName(state: State) {
}
export function selectCredential(state: State) {
- return new VCMetadata(state.context.selectedVc?.vcMetadata).isFromOpenId4VCI()
- ? state.context.selectedVc?.verifiableCredential?.credential
- : state.context.selectedVc?.verifiableCredential;
+ return (
+ state.context.selectedVc?.verifiableCredential?.credential ||
+ state.context.selectedVc?.verifiableCredential
+ );
}
export function selectVerifiableCredentialData(state: State) {
const vcMetadata = new VCMetadata(state.context.selectedVc?.vcMetadata);
- return vcMetadata.isFromOpenId4VCI()
- ? {
- vcMetadata: vcMetadata,
- issuer: vcMetadata.issuer,
- issuerLogo: state.context.selectedVc?.verifiableCredential?.issuerLogo,
- wellKnown: state.context.selectedVc?.verifiableCredential?.wellKnown,
- face: state.context.selectedVc?.verifiableCredential?.credential
- .credentialSubject?.face,
- credentialTypes:
- state.context.selectedVc?.verifiableCredential?.credentialTypes,
- }
- : {
- vcMetadata: vcMetadata,
- issuer: vcMetadata.issuer,
- face: state.context.selectedVc?.credential?.biometrics?.face,
- issuerLogo: getMosipLogo(),
- };
+ return {
+ vcMetadata: vcMetadata,
+ issuer: vcMetadata.issuer,
+ issuerLogo:
+ state.context.selectedVc?.verifiableCredential?.issuerLogo ||
+ getMosipLogo(),
+ face:
+ state.context.selectedVc?.verifiableCredential?.credential
+ ?.credentialSubject?.face ||
+ state.context.selectedVc?.credential?.biometrics?.face,
+ wellKnown: state.context.selectedVc?.verifiableCredential?.wellKnown,
+ credentialTypes:
+ state.context.selectedVc?.verifiableCredential?.credentialTypes,
+ };
}
export function selectQrLoginRef(state: State) {
diff --git a/machines/faceScanner.typegen.ts b/machines/faceScanner.typegen.ts
index 17757e15..b7e60e89 100644
--- a/machines/faceScanner.typegen.ts
+++ b/machines/faceScanner.typegen.ts
@@ -1,47 +1,71 @@
+// 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.faceScanner.capturing:invocation[0]": { type: "done.invoke.faceScanner.capturing:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
-"done.invoke.faceScanner.verifying:invocation[0]": { type: "done.invoke.faceScanner.verifying:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
-"error.platform.faceScanner.capturing:invocation[0]": { type: "error.platform.faceScanner.capturing:invocation[0]"; data: unknown };
-"xstate.init": { type: "xstate.init" };
- };
- invokeSrcNameMap: {
- "captureImage": "done.invoke.faceScanner.capturing:invocation[0]";
-"checkPermission": "done.invoke.faceScanner.init.checkingPermission:invocation[0]";
-"requestPermission": "done.invoke.faceScanner.init.requestingPermission:invocation[0]";
-"verifyImage": "done.invoke.faceScanner.verifying:invocation[0]";
- };
- missingImplementations: {
- actions: never;
- delays: never;
- guards: never;
- services: never;
- };
- eventsCausingActions: {
- "flipWhichCamera": "FLIP_CAMERA";
-"openSettings": "OPEN_SETTINGS";
-"setCameraRef": "READY";
-"setCaptureError": "error.platform.faceScanner.capturing:invocation[0]";
-"setCapturedImage": "done.invoke.faceScanner.capturing:invocation[0]";
- };
- eventsCausingDelays: {
-
- };
- eventsCausingGuards: {
- "canRequestPermission": "DENIED";
-"doesFaceMatch": "done.invoke.faceScanner.verifying:invocation[0]";
- };
- eventsCausingServices: {
- "captureImage": "CAPTURE";
-"checkPermission": "APP_FOCUSED" | "xstate.init";
-"requestPermission": "DENIED";
-"verifyImage": "done.invoke.faceScanner.capturing:invocation[0]";
- };
- matchesStates: "capturing" | "init" | "init.checkingPermission" | "init.permissionDenied" | "init.permissionGranted" | "init.requestingPermission" | "invalid" | "scanning" | "valid" | "verifying" | { "init"?: "checkingPermission" | "permissionDenied" | "permissionGranted" | "requestingPermission"; };
- tags: never;
- }
-
\ No newline at end of file
+export interface Typegen0 {
+ '@@xstate/typegen': true;
+ internalEvents: {
+ 'done.invoke.faceScanner.capturing:invocation[0]': {
+ type: 'done.invoke.faceScanner.capturing:invocation[0]';
+ data: unknown;
+ __tip: 'See the XState TS docs to learn how to strongly type this.';
+ };
+ 'done.invoke.faceScanner.verifying:invocation[0]': {
+ type: 'done.invoke.faceScanner.verifying:invocation[0]';
+ data: unknown;
+ __tip: 'See the XState TS docs to learn how to strongly type this.';
+ };
+ 'error.platform.faceScanner.capturing:invocation[0]': {
+ type: 'error.platform.faceScanner.capturing:invocation[0]';
+ data: unknown;
+ };
+ 'xstate.init': {type: 'xstate.init'};
+ };
+ invokeSrcNameMap: {
+ captureImage: 'done.invoke.faceScanner.capturing:invocation[0]';
+ checkPermission: 'done.invoke.faceScanner.init.checkingPermission:invocation[0]';
+ requestPermission: 'done.invoke.faceScanner.init.requestingPermission:invocation[0]';
+ verifyImage: 'done.invoke.faceScanner.verifying:invocation[0]';
+ };
+ missingImplementations: {
+ actions: never;
+ delays: never;
+ guards: never;
+ services: never;
+ };
+ eventsCausingActions: {
+ flipWhichCamera: 'FLIP_CAMERA';
+ openSettings: 'OPEN_SETTINGS';
+ setCameraRef: 'READY';
+ setCaptureError: 'error.platform.faceScanner.capturing:invocation[0]';
+ setCapturedImage: 'done.invoke.faceScanner.capturing:invocation[0]';
+ };
+ eventsCausingDelays: {};
+ eventsCausingGuards: {
+ canRequestPermission: 'DENIED';
+ doesFaceMatch: 'done.invoke.faceScanner.verifying:invocation[0]';
+ };
+ eventsCausingServices: {
+ captureImage: 'CAPTURE';
+ checkPermission: 'APP_FOCUSED' | 'xstate.init';
+ requestPermission: 'DENIED';
+ verifyImage: 'done.invoke.faceScanner.capturing:invocation[0]';
+ };
+ matchesStates:
+ | 'capturing'
+ | 'init'
+ | 'init.checkingPermission'
+ | 'init.permissionDenied'
+ | 'init.permissionGranted'
+ | 'init.requestingPermission'
+ | 'invalid'
+ | 'scanning'
+ | 'valid'
+ | 'verifying'
+ | {
+ init?:
+ | 'checkingPermission'
+ | 'permissionDenied'
+ | 'permissionGranted'
+ | 'requestingPermission';
+ };
+ tags: never;
+}
diff --git a/machines/settings.ts b/machines/settings.ts
index 1ffc9261..69fca0ee 100644
--- a/machines/settings.ts
+++ b/machines/settings.ts
@@ -390,4 +390,4 @@ export function selectIsPasscodeUnlock(state: State) {
return (
state.context.isBiometricToggled && !state.context.isBiometricUnlockEnabled
);
-}
\ No newline at end of file
+}
diff --git a/machines/settings.typegen.ts b/machines/settings.typegen.ts
index 0be916ed..37a729a1 100644
--- a/machines/settings.typegen.ts
+++ b/machines/settings.typegen.ts
@@ -1,53 +1,70 @@
+// 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.settings.resetInjiProps:invocation[0]": { type: "done.invoke.settings.resetInjiProps:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
-"error.platform.settings.resetInjiProps:invocation[0]": { type: "error.platform.settings.resetInjiProps:invocation[0]"; data: unknown };
-"xstate.init": { type: "xstate.init" };
- };
- invokeSrcNameMap: {
- "resetInjiProps": "done.invoke.settings.resetInjiProps:invocation[0]";
- };
- missingImplementations: {
- actions: never;
- delays: never;
- guards: never;
- services: never;
- };
- eventsCausingActions: {
- "requestStoredContext": "xstate.init";
-"resetCredentialRegistryResponse": "CANCEL" | "UPDATE_HOST";
-"resetIsBiometricToggled": "DISMISS";
-"setBackupAndRestoreOptionExplored": "SET_IS_BACKUP_AND_RESTORE_EXPLORED";
-"setContext": "STORE_RESPONSE";
-"setIsBiometricToggled": "TOGGLE_BIOMETRIC_UNLOCK";
-"storeContext": "ACCEPT_HARDWARE_SUPPORT_NOT_EXISTS" | "SET_IS_BACKUP_AND_RESTORE_EXPLORED" | "SHOWN_ACCOUNT_SELECTION_CONFIRMATION" | "STORE_RESPONSE" | "TOGGLE_BIOMETRIC_UNLOCK" | "UPDATE_HOST" | "UPDATE_NAME" | "UPDATE_VC_LABEL" | "done.invoke.settings.resetInjiProps:invocation[0]";
-"toggleBiometricUnlock": "TOGGLE_BIOMETRIC_UNLOCK";
-"updateCredentialRegistry": "done.invoke.settings.resetInjiProps:invocation[0]";
-"updateCredentialRegistryResponse": "error.platform.settings.resetInjiProps:invocation[0]";
-"updateCredentialRegistrySuccess": "done.invoke.settings.resetInjiProps:invocation[0]";
-"updateDefaults": "STORE_RESPONSE";
-"updateEsignetHostUrl": "UPDATE_HOST";
-"updateIsAccountSelectionConfirmationShown": "SHOWN_ACCOUNT_SELECTION_CONFIRMATION";
-"updateName": "UPDATE_NAME";
-"updatePartialDefaults": "STORE_RESPONSE";
-"updateUserShownWithHardwareKeystoreNotExists": "ACCEPT_HARDWARE_SUPPORT_NOT_EXISTS";
-"updateVcLabel": "UPDATE_VC_LABEL";
- };
- eventsCausingDelays: {
-
- };
- eventsCausingGuards: {
- "hasData": "STORE_RESPONSE";
-"hasPartialData": "STORE_RESPONSE";
- };
- eventsCausingServices: {
- "resetInjiProps": "UPDATE_HOST";
- };
- matchesStates: "idle" | "init" | "resetInjiProps" | "showInjiTourGuide" | "storingDefaults";
- tags: never;
- }
-
\ No newline at end of file
+export interface Typegen0 {
+ '@@xstate/typegen': true;
+ internalEvents: {
+ 'done.invoke.settings.resetInjiProps:invocation[0]': {
+ type: 'done.invoke.settings.resetInjiProps:invocation[0]';
+ data: unknown;
+ __tip: 'See the XState TS docs to learn how to strongly type this.';
+ };
+ 'error.platform.settings.resetInjiProps:invocation[0]': {
+ type: 'error.platform.settings.resetInjiProps:invocation[0]';
+ data: unknown;
+ };
+ 'xstate.init': {type: 'xstate.init'};
+ };
+ invokeSrcNameMap: {
+ resetInjiProps: 'done.invoke.settings.resetInjiProps:invocation[0]';
+ };
+ missingImplementations: {
+ actions: never;
+ delays: never;
+ guards: never;
+ services: never;
+ };
+ eventsCausingActions: {
+ requestStoredContext: 'xstate.init';
+ resetCredentialRegistryResponse: 'CANCEL' | 'UPDATE_HOST';
+ resetIsBiometricToggled: 'DISMISS';
+ setBackupAndRestoreOptionExplored: 'SET_IS_BACKUP_AND_RESTORE_EXPLORED';
+ setContext: 'STORE_RESPONSE';
+ setIsBiometricToggled: 'TOGGLE_BIOMETRIC_UNLOCK';
+ storeContext:
+ | 'ACCEPT_HARDWARE_SUPPORT_NOT_EXISTS'
+ | 'SET_IS_BACKUP_AND_RESTORE_EXPLORED'
+ | 'SHOWN_ACCOUNT_SELECTION_CONFIRMATION'
+ | 'STORE_RESPONSE'
+ | 'TOGGLE_BIOMETRIC_UNLOCK'
+ | 'UPDATE_HOST'
+ | 'UPDATE_NAME'
+ | 'UPDATE_VC_LABEL'
+ | 'done.invoke.settings.resetInjiProps:invocation[0]';
+ toggleBiometricUnlock: 'TOGGLE_BIOMETRIC_UNLOCK';
+ updateCredentialRegistry: 'done.invoke.settings.resetInjiProps:invocation[0]';
+ updateCredentialRegistryResponse: 'error.platform.settings.resetInjiProps:invocation[0]';
+ updateCredentialRegistrySuccess: 'done.invoke.settings.resetInjiProps:invocation[0]';
+ updateDefaults: 'STORE_RESPONSE';
+ updateEsignetHostUrl: 'UPDATE_HOST';
+ updateIsAccountSelectionConfirmationShown: 'SHOWN_ACCOUNT_SELECTION_CONFIRMATION';
+ updateName: 'UPDATE_NAME';
+ updatePartialDefaults: 'STORE_RESPONSE';
+ updateUserShownWithHardwareKeystoreNotExists: 'ACCEPT_HARDWARE_SUPPORT_NOT_EXISTS';
+ updateVcLabel: 'UPDATE_VC_LABEL';
+ };
+ eventsCausingDelays: {};
+ eventsCausingGuards: {
+ hasData: 'STORE_RESPONSE';
+ hasPartialData: 'STORE_RESPONSE';
+ };
+ eventsCausingServices: {
+ resetInjiProps: 'UPDATE_HOST';
+ };
+ matchesStates:
+ | 'idle'
+ | 'init'
+ | 'resetInjiProps'
+ | 'showInjiTourGuide'
+ | 'storingDefaults';
+ tags: never;
+}
diff --git a/machines/store.ts b/machines/store.ts
index f0134be5..915eb46a 100644
--- a/machines/store.ts
+++ b/machines/store.ts
@@ -77,6 +77,7 @@ const model = createModel(
requester,
}),
STORE_ERROR: (error: Error, requester?: string) => ({error, requester}),
+ FETCH_ALL_WELLKNOWN_CONFIG: () => ({}),
},
},
);
@@ -233,6 +234,9 @@ export const storeMachine =
CLEAR: {
actions: 'forwardStoreRequest',
},
+ FETCH_ALL_WELLKNOWN_CONFIG: {
+ actions: 'forwardStoreRequest',
+ },
STORE_RESPONSE: {
actions: [
send(
@@ -442,6 +446,13 @@ export const storeMachine =
await clear();
break;
}
+ case 'FETCH_ALL_WELLKNOWN_CONFIG': {
+ response = await fetchAllWellknownConfig(
+ context.encryptionKey,
+ );
+ break;
+ }
+
default:
return;
}
@@ -586,6 +597,10 @@ export async function loadBackupData(data, encryptionKey) {
await Storage.loadBackupData(data, encryptionKey);
}
+export async function fetchAllWellknownConfig(encryptionKey: string) {
+ return await Storage.fetchAllWellknownConfig(encryptionKey);
+}
+
export async function getVCsData(key: string, encryptionKey: string) {
try {
let vcsData: Record = {};
diff --git a/machines/store.typegen.ts b/machines/store.typegen.ts
index dac36268..bbcd79c7 100644
--- a/machines/store.typegen.ts
+++ b/machines/store.typegen.ts
@@ -35,6 +35,7 @@ export interface Typegen0 {
| 'APPEND'
| 'CLEAR'
| 'EXPORT'
+ | 'FETCH_ALL_WELLKNOWN_CONFIG'
| 'GET'
| 'GET_VCS_DATA'
| 'PREPEND'
diff --git a/screens/History/HistoryScreenController.ts b/screens/History/HistoryScreenController.ts
index a7a5b303..a7a7eeb7 100644
--- a/screens/History/HistoryScreenController.ts
+++ b/screens/History/HistoryScreenController.ts
@@ -1,21 +1,30 @@
-import { useSelector } from '@xstate/react';
-import { useContext } from 'react';
+import {useSelector} from '@xstate/react';
+import {useContext} from 'react';
import {
ActivityLogEvents,
selectActivities,
selectIsRefreshing,
+ selectWellknownIssuerMap,
} from '../../machines/activityLog';
-import { GlobalContext } from '../../shared/GlobalContext';
+import {GlobalContext} from '../../shared/GlobalContext';
export function useHistoryTab() {
- const { appService } = useContext(GlobalContext);
- const activityLogService = appService.children.get('activityLog');
+ const {appService} = useContext(GlobalContext);
+ const activityLogService = appService.children.get('activityLog')!!;
+ const wellknownIssuerMap = useSelector(
+ activityLogService,
+ selectWellknownIssuerMap,
+ );
return {
activities: useSelector(activityLogService, selectActivities),
isRefreshing: useSelector(activityLogService, selectIsRefreshing),
+ getWellKnownIssuerMap: (issuerName: string) => {
+ return wellknownIssuerMap[issuerName] ?? null;
+ },
+
REFRESH: () => activityLogService.send(ActivityLogEvents.REFRESH()),
};
}
diff --git a/screens/Home/ViewVcModal.tsx b/screens/Home/ViewVcModal.tsx
index 4bd289f5..efbb8edf 100644
--- a/screens/Home/ViewVcModal.tsx
+++ b/screens/Home/ViewVcModal.tsx
@@ -134,9 +134,7 @@ export const ViewVcModal: React.FC = props => {
item.id}
renderItem={({item}) => {
diff --git a/screens/Issuers/IssuerScreenController.tsx b/screens/Issuers/IssuerScreenController.tsx
index 8231aeff..29e3c804 100644
--- a/screens/Issuers/IssuerScreenController.tsx
+++ b/screens/Issuers/IssuerScreenController.tsx
@@ -1,6 +1,6 @@
import {useSelector} from '@xstate/react';
import {
- selectCredentialTypes,
+ selectSupportedCredentialTypes,
selectErrorMessageType,
selectIsBiometricCancelled,
selectIsDone,
@@ -41,7 +41,10 @@ export function useIssuerScreenController({route, navigation}) {
service,
selectSelectingCredentialType,
),
- credentialTypes: useSelector(service, selectCredentialTypes),
+ supportedCredentialTypes: useSelector(
+ service,
+ selectSupportedCredentialTypes,
+ ),
verificationErrorMessage: useSelector(
service,
selectVerificationErrorMessage,
diff --git a/screens/QrLogin/QrLogin.tsx b/screens/QrLogin/QrLogin.tsx
index 4efebd23..9e821efd 100644
--- a/screens/QrLogin/QrLogin.tsx
+++ b/screens/QrLogin/QrLogin.tsx
@@ -12,7 +12,7 @@ import {Icon} from 'react-native-elements';
import {View} from 'react-native';
import {FaceVerificationAlertOverlay} from '../Scan/FaceVerificationAlertOverlay';
import {SvgImage} from '../../components/ui/svg';
-import { LIVENESS_CHECK } from '../../shared/constants';
+import {LIVENESS_CHECK} from '../../shared/constants';
export const QrLogin: React.FC = props => {
const controller = useQrLogin(props);
diff --git a/screens/Scan/ScanLayout.tsx b/screens/Scan/ScanLayout.tsx
index 142aaf40..b54e6dfc 100644
--- a/screens/Scan/ScanLayout.tsx
+++ b/screens/Scan/ScanLayout.tsx
@@ -15,7 +15,7 @@ import {SvgImage} from '../../components/ui/svg';
import {View, I18nManager} from 'react-native';
import {Text} from './../../components/ui';
import {BannerStatusType} from '../../components/BannerNotification';
-import { LIVENESS_CHECK } from '../../shared/constants';
+import {LIVENESS_CHECK} from '../../shared/constants';
const ScanStack = createNativeStackNavigator();
diff --git a/screens/Scan/SendVcScreen.tsx b/screens/Scan/SendVcScreen.tsx
index d90dbb21..63e5a403 100644
--- a/screens/Scan/SendVcScreen.tsx
+++ b/screens/Scan/SendVcScreen.tsx
@@ -17,13 +17,13 @@ import {
import {TelemetryConstants} from '../../shared/telemetry/TelemetryConstants';
import {
getVCsOrderedByPinStatus,
+ isMosipVC,
VCItemContainerFlowType,
} from '../../shared/Utils';
-import {Issuers} from '../../shared/openId4VCI/Utils';
import {FaceVerificationAlertOverlay} from './FaceVerificationAlertOverlay';
import {Error} from '../../components/ui/Error';
import {SvgImage} from '../../components/ui/svg';
-import { LIVENESS_CHECK } from '../../shared/constants';
+import {LIVENESS_CHECK} from '../../shared/constants';
export const SendVcScreen: React.FC = () => {
const {t} = useTranslation('SendVcScreen');
@@ -102,9 +102,7 @@ export const SendVcScreen: React.FC = () => {
- {[Issuers.MosipOtp, Issuers.Mosip].indexOf(
- controller.verifiableCredentialData.issuer,
- ) !== -1 && (
+ {isMosipVC(controller.verifiableCredentialData.issuer) && (