Refactor(inji-429) : standardize issuers configuration (#937)

* refactor(inji-429): standardize the issuers configuration

Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com>

* refactor(inji-249): optimise the issuers protocols implementations

Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com>

* refactor(inji-249): remove unnecessary states and unused icons

Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com>

---------

Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com>
This commit is contained in:
vijay151096
2023-10-18 17:23:11 +05:30
committed by GitHub
parent 2bb82baf97
commit ad76243d02
24 changed files with 338 additions and 460 deletions

3
.env
View File

@@ -19,6 +19,3 @@ DEBUG_MODE=false
#supported languages( en, fil, ar, hi, kn, ta)
APPLICATION_LANGUAGE=en
#Toggle for openID for VC
ENABLE_OPENID_FOR_VC=true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1,6 +1,6 @@
import React from 'react';
import {useTranslation} from 'react-i18next';
import {Image, ImageBackground, View} from 'react-native';
import {Image, ImageBackground} from 'react-native';
import {getLocalizedField} from '../../../i18n';
import {VerifiableCredential} from '../../../types/VC/ExistingMosipVC/vc';
import VerifiedIcon from '../../VerifiedIcon';
@@ -8,6 +8,7 @@ import {Column, Row, Text} from '../../ui';
import {Theme} from '../../ui/styleUtils';
import {CheckBox, Icon} from 'react-native-elements';
import testIDProps from '../../../shared/commonUtil';
import {logoType} from '../../../machines/issuersMachine';
const getDetails = (arg1, arg2, verifiableCredential) => {
if (arg1 === 'Status') {
@@ -87,11 +88,12 @@ function getIdNumber(id: string) {
return '*'.repeat(id.length - 4) + id.slice(-4);
}
const getIssuerLogo = (isOpenId4VCI: boolean, issuerLogo: string) => {
const getIssuerLogo = (isOpenId4VCI: boolean, issuerLogo: logoType) => {
if (isOpenId4VCI) {
return (
<Image
src={issuerLogo}
src={issuerLogo?.url}
alt={issuerLogo?.alt_text}
style={Theme.Styles.issuerLogo}
resizeMethod="scale"
resizeMode="contain"

View File

@@ -4,7 +4,7 @@ import * as DateFnsLocale from 'date-fns/locale';
import {useTranslation} from 'react-i18next';
import {Dimensions, Image, ImageBackground, View} from 'react-native';
import {Icon} from 'react-native-elements';
import {VC, CredentialSubject} from '../../../types/VC/ExistingMosipVC/vc';
import {CredentialSubject, VC} from '../../../types/VC/ExistingMosipVC/vc';
import {Button, Column, Row, Text} from '../../ui';
import {Theme} from '../../ui/styleUtils';
import {TextItem} from '../../ui/TextItem';
@@ -20,10 +20,17 @@ import {
VerifiablePresentation,
} from '../../../types/VC/EsignetMosipVC/vc';
import {WalletBindingResponse} from '../../../shared/cryptoutil/cryptoUtil';
import {logoType} from '../../../machines/issuersMachine';
const getIssuerLogo = (isOpenId4VCI: boolean, issuerLogo: string) => {
const getIssuerLogo = (isOpenId4VCI: boolean, issuerLogo: logoType) => {
if (isOpenId4VCI) {
return <Image src={issuerLogo} style={Theme.Styles.issuerLogo} />;
return (
<Image
src={issuerLogo?.url}
alt={issuerLogo?.alt_text}
style={Theme.Styles.issuerLogo}
/>
);
}
return <Image source={Theme.MosipLogo} style={Theme.Styles.vcDetailsLogo} />;
};

View File

@@ -9,8 +9,7 @@ export const Issuer: React.FC<IssuerProps> = (props: IssuerProps) => {
const {t} = useTranslation('IssuersScreen');
function getIssuerLogo() {
if (props.logoUrl) return {uri: props.logoUrl};
return Theme.DigitIcon;
return {uri: props.logoUrl};
}
return (

View File

@@ -1261,7 +1261,6 @@ export const DefaultTheme = {
protectPrivacy: require('../../../assets/intro-unlock-method.png'),
NoInternetConnection: require('../../../assets/no-internet-connection.png'),
SomethingWentWrong: require('../../../assets/something-went-wrong.png'),
DigitIcon: require('../../../assets/digit-icon.png'),
elevation(level: ElevationLevel): ViewStyle {
// https://ethercreative.github.io/react-native-shadow-generator/

View File

@@ -1259,7 +1259,6 @@ export const PurpleTheme = {
protectPrivacy: require('../../../assets/intro-unlock-method.png'),
NoInternetConnection: require('../../../assets/no-internet-connection.png'),
SomethingWentWrong: require('../../../assets/something-went-wrong.png'),
DigitIcon: require('../../../assets/digit-icon.png'),
elevation(level: ElevationLevel): ViewStyle {
// https://ethercreative.github.io/react-native-shadow-generator/

View File

@@ -9,7 +9,7 @@ import {
WalletBindingResponse,
} from '../../../shared/cryptoutil/cryptoUtil';
import {log} from 'xstate/lib/actions';
import {OpenId4VCIProtocol} from '../../../shared/openId4VCI/Utils';
import {Protocols} from '../../../shared/openId4VCI/Utils';
import {StoreEvents} from '../../../machines/store';
import {MIMOTO_BASE_URL, MY_VCS_STORE_KEY} from '../../../shared/constants';
import {VcEvents} from '../../../machines/vc';
@@ -500,7 +500,7 @@ export const EsignetMosipVCItemMachine = model.createMachine(
context => ({
type: 'GET_VC_ITEM',
vcMetadata: context.vcMetadata,
protocol: OpenId4VCIProtocol,
protocol: Protocols.OpenId4VCI,
}),
{
to: context => context.serviceRefs.vc,

View File

@@ -1,64 +1,47 @@
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'': {type: ''};
'done.invoke.auth.authorized:invocation[0]': {
type: 'done.invoke.auth.authorized:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.auth.introSlider:invocation[0]': {
type: 'done.invoke.auth.introSlider:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
downloadFaceSdkModel: 'done.invoke.auth.authorized:invocation[0]';
generatePasscodeSalt: 'done.invoke.auth.introSlider:invocation[0]';
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
requestStoredContext: 'xstate.init';
setBiometrics: 'SETUP_BIOMETRICS';
setContext: 'STORE_RESPONSE';
setLanguage: 'SETUP_BIOMETRICS' | 'SETUP_PASSCODE';
setPasscode: 'SETUP_PASSCODE';
setPasscodeSalt: 'done.invoke.auth.introSlider:invocation[0]';
storeContext:
| 'SETUP_BIOMETRICS'
| 'SETUP_PASSCODE'
| 'STORE_RESPONSE'
| 'done.invoke.auth.authorized:invocation[0]'
| 'done.invoke.auth.introSlider:invocation[0]';
};
eventsCausingDelays: {};
eventsCausingGuards: {
hasBiometricSet: '';
hasData: 'STORE_RESPONSE';
hasLanguageset: '';
hasPasscodeSet: '';
};
eventsCausingServices: {
downloadFaceSdkModel: 'LOGIN' | 'SETUP_PASSCODE';
generatePasscodeSalt: 'SELECT';
};
matchesStates:
| 'authorized'
| 'checkingAuth'
| 'init'
| 'introSlider'
| 'languagesetup'
| 'savingDefaults'
| 'settingUp'
| 'unauthorized';
tags: never;
}
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"": { type: "" };
"done.invoke.auth.authorized:invocation[0]": { type: "done.invoke.auth.authorized:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.auth.introSlider:invocation[0]": { type: "done.invoke.auth.introSlider:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"xstate.init": { type: "xstate.init" };
};
invokeSrcNameMap: {
"downloadFaceSdkModel": "done.invoke.auth.authorized:invocation[0]";
"generatePasscodeSalt": "done.invoke.auth.introSlider:invocation[0]";
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
"requestStoredContext": "xstate.init";
"setBiometrics": "SETUP_BIOMETRICS";
"setContext": "STORE_RESPONSE";
"setLanguage": "SETUP_BIOMETRICS" | "SETUP_PASSCODE";
"setPasscode": "SETUP_PASSCODE";
"setPasscodeSalt": "done.invoke.auth.introSlider:invocation[0]";
"storeContext": "SETUP_BIOMETRICS" | "SETUP_PASSCODE" | "STORE_RESPONSE" | "done.invoke.auth.authorized:invocation[0]" | "done.invoke.auth.introSlider:invocation[0]";
};
eventsCausingDelays: {
};
eventsCausingGuards: {
"hasBiometricSet": "";
"hasData": "STORE_RESPONSE";
"hasLanguageset": "";
"hasPasscodeSet": "";
};
eventsCausingServices: {
"downloadFaceSdkModel": "LOGIN" | "SETUP_PASSCODE";
"generatePasscodeSalt": "SELECT";
};
matchesStates: "authorized" | "checkingAuth" | "init" | "introSlider" | "languagesetup" | "savingDefaults" | "settingUp" | "unauthorized";
tags: never;
}

View File

@@ -20,6 +20,9 @@ import {
vcDownloadTimeout,
OIDCErrors,
ErrorMessage,
updateCredentialInformation,
constructAuthorizationConfiguration,
getVCMetadata,
} from '../shared/openId4VCI/Utils';
import {NETWORK_REQUEST_FAILED, REQUEST_TIMEOUT} from '../shared/constants';
import {VCMetadata} from '../shared/VCMetadata';
@@ -68,7 +71,7 @@ const model = createModel(
export const IssuerScreenTabEvents = model.events;
export const Issuer_Tab_Ref_Id = 'issuersMachine';
export const Issuers_Key_Ref = 'OpenId4VCI';
export const Issuers_Key_Ref = 'OpenId4VCI_KeyPair';
export const IssuersMachine = model.createMachine(
{
/** @xstate-layout N4IgpgJg5mDOIC5QEtawK5gE6wLIEMBjAC2QDswA6CVABwBt8BPASTUxwGIIB7Cy8gDceAayqoM2PEVL8asBszaScCIT0L4ALsj4BtAAwBdQ0cShaPWMh19zIAB6IALAEYAnJWfuAzM4BsAKwAHN7BwQDsfgA0IEyIAEw+Ea6UBgkRwT7uEekGrhHOAL5FsRIc0iTkVPKKrOxSnNhYPFiUiloAZq0AtgINOARVcnSM9SqwamTCmrZkpqb2ltZz9k4Izgme3n5Boe7hUc6x8QgJ3gZpgT6BgRH+yYWBJWUDlbJUza2cACoASgBNAD6AEEAOIglgAOUWSBAyxsujIaxcWy8vgCITCkRicUSIQSlGyCQMETu7n84QKLxA5SkQw+lC+WF+gNBEOhelcZjhCNWcPWrgSJ0QQppdMGMmqTKwLRZ-2B4MhMISPIsVkRdgFooMvjS-jc9wezl1ARFZwiCUClFcN3czmcKWuPnFbwZ0uZnD+AFEAMren5A71-P4AeT+sPVKyRKIQrgMwX8lASCWCgVcgW8lt15oyEU8CSCloz6WcN38rom7v4sDA9DAhB0ZCgyg4nAAIqGAOpQgAyoZB7aBLHbkfhGv5oHWPgMBmclEigQM-lTVpyc9z+R8yfzriyPhTS4zlYq1aotfrjfILYGnH9ve9AGEft6hyxfb6AKrBsd8mPahBAmFPEEB8VwhS8XVkgKA5dXcE96SlOQeAAdzIegeHwCBW2wR8+E6ZAoG4PhxGmURxDdJCalQ9DMOwgY8LIAioCmGZtCRBZjCWCd-ynUVgNOMVSlpSjhmotCMKwnCsEY5imllVp2kYLpen6KsqOoGjJPolRZMI1iNHY-RjF-HitT4jYUwXZwgMpFMfHCGcIlze15zuFdghyA5UweBDJTEygSAbEQWDILRsAoLRiP4dQxEC4hgtC8KsEi0zo3MxxRVuQlLUCdxdUzbIhX8c14w8Iky1ucI1zTYI-PeaUgsIEKwoisAot4GKyLipqWuS1LuW49LkQA4I0SFdxwOXO1-HSUrbUuLZSX8XwMn8Vwy3qs94sS1qUva+S5SU7RuiwPpeqStqtDSzURos4IIMpB5i1moCHPNSbgi8QIDXcPLcltDIto0i69simU5QSVlFQ5GEuN5My7syuNkiTfJJvyDwiyCUrZ2tPwbimoDMhuYGAtobBTp6EF0C0YhWmQAAvIyyGi0jhDiiUGv4CmsCpmm6YZ5m5gM2YOJM+Go1u2NbJtFbJoyN7U3cc0V2tbxXH8FdHSPe0ycZXn+dp+msCZlnDsUjoqbU08NMN3oBZNs2RfUMXjJMSXx2GmXNbl9wFbJJJlfNB6bUiLYbiW-KIgifXpXts7HaF83mWOlSzptxDycph3jeTl2yLd+YTMGhHvYA64k01-2hUDg9PNK5J52CAwZ3TQpwNj4Sue23qAGkwCYAAFfBkBZR8AAknz7oE++9YEh8hCNPb-DLBTnKuPD+h15cKc0qptDaMcibxnm70TGX7weR7HzhJ+n2f56BReWAjUupcnZH4x8Tf-czAJ-Z7xAskS4YFiQeXOJ5F0591IBRgBQLA2gwAD2HqPFknV2bkUzv5Rk8DsBIJQTfLAosWacTVF7aWAECjZEoPlTy6Z1o5HOOaPwqRqoOQyGNTMKY478DwYg8KhC0FswEN1CisDcFgAQQQ6+aCSFzAWO-Chn9BRRE8HQv6msPCWmOCBFMhI0xBH8DHMkOQyS8PErRLCj4sCQCkTofA9BYAiNiuI22AVeASTojYuxYVkCOMmK7UhEtyGryRusGyER9SWgpIVCkYFAi5j3EmG4CZW4OSbsUGB7jGSeKsRAHxEB7H+KcRbNoVtVI9w0nk7ShTikBPkeLD2oTEaxkidErYQQyzxIzLmThlBKSrQzJsKkFjNJeOsbYopfiAl3xBFCR83pew3RUS4R0HTYndIeL0kCe4ogVSyB4ByMcNpjMENgZAnQmDXjqTM+gLixHYO5lQc5psrk3KmfU+gjT3YrN4l-eMnguF3HOAkDMDlEl6ITFXYxDosjnCONA14EjpSvMudc5styHH3NThUjOVSApoveZiz5dyfnF2aUNShFkppAqtCCzY4K0x9IMNafMDCDgPBJAeMZyAID1jvqGXAQ8HwvlHCvVpVC1ZeG5VsVMUQ9l9JNAM5wY0W6pnjJEXl-KwBzIWUsv5a9RTSs2K3OVOJFV6NtKkG4eVUytx+jymkZAeBFPgHCAlHwqWrIQAAWh-uaX1ZIw6WnuJVKIK0EhjNqGMaS7qP7-PWJaXMP0okmhTPmGOFJ4wVmyVnRkzJvWJsQC3IFOQNqJkKPmG4uZMiXF1JSTYhZ0i7DGReBsTYbwqCLUauMu4iRUh+pmIUG0km2gGQURMqNNibTzTg6UNS6LST0lAHt4TEDGJcoWWhI6xreACGSXNyKcmNQSs1S6+0tBrtjGGgZU6XqsqSMEc0ZJtwFRNAUHeGYz7Hvzae3a-V2oQ1aAka9VCwVROhS3PKfhlwFA+mNZMjxcgORskkI9IkUU8xzonPOpthb-LCW0gSoofB+C8GNFaLd4zLhjmMq+qCx5gYsoehcMcbi7g2imVW5H0yqrGjcPwlo6pzueZQfhMjGNYGY1-PwhISQFGeoJlILCwJeHWhmBVFahK-vnchCZBTSXYvjco4tCAch9LU7Va48ZHSUjORc4lUAsUlJk+sQZyYqrrgNFrZ9VrKR3uMR5TWZGf5tq0AzZsbnSO+0NNkNwbhHKQsEv7bcar8pgW8FsUI2r6zRZRhmNIMdVy5Dyuqyz84AhPXsqqlI0aSL5ZgjawdXSR26NOCmX2WxHS6k-Xxs+JQgA */
@@ -171,7 +174,8 @@ export const IssuersMachine = model.createMachine(
},
],
onError: {
actions: () => console.log('checkInternet error caught'),
actions: () =>
console.log('Error Occurred while checking Internet'),
target: 'error',
},
},
@@ -205,7 +209,11 @@ export const IssuersMachine = model.createMachine(
actions: [
'setError',
'resetLoadingReason',
(_, event) => console.log('error in invokeAuth - ', event.data),
(_, event) =>
console.log(
'Error Occurred while invoking Auth - ',
event.data,
),
],
target: 'error',
},
@@ -499,7 +507,7 @@ export const IssuersMachine = model.createMachine(
const downloadTimeout = await vcDownloadTimeout();
let credential = await request(
'POST',
context.selectedIssuer.serviceConfiguration.credentialEndpoint,
context.selectedIssuer.credential_endpoint,
body,
'',
{
@@ -518,10 +526,12 @@ export const IssuersMachine = model.createMachine(
sendImpressionEvent(
getImpressionEventData(
'VC Download',
context.selectedIssuer.id + ' Web View Page',
context.selectedIssuer.credential_issuer + ' Web View Page',
),
);
return await authorize(context.selectedIssuer);
return await authorize(
constructAuthorizationConfiguration(context.selectedIssuer),
);
},
generateKeyPair: async context => {
if (!isCustomSecureKeystore()) {
@@ -607,32 +617,27 @@ export function selectStoring(state: State) {
return state.matches('storing');
}
interface issuerType {
id: string;
displayName: string;
logoUrl: string;
export interface logoType {
url: string;
alt_text: string;
}
const updateCredentialInformation = (context, credential) => {
let credentialWrapper: CredentialWrapper = {};
credentialWrapper.verifiableCredential = credential;
credentialWrapper.verifiableCredential.issuerLogo =
context.selectedIssuer.logoUrl;
credentialWrapper.identifier = getIdentifier(context, credential);
credentialWrapper.generatedOn = new Date();
credentialWrapper.issuerLogo = context.selectedIssuer.logoUrl;
return credentialWrapper;
};
const getVCMetadata = context => {
const [issuer, protocol, requestId] =
context.credentialWrapper?.identifier.split(':');
return VCMetadata.fromVC({
requestId: requestId ? requestId : null,
issuer: issuer,
protocol: protocol,
id: context.verifiableCredential?.credential.credentialSubject.UIN
? context.verifiableCredential?.credential.credentialSubject.UIN
: context.verifiableCredential?.credential.credentialSubject.VID,
});
};
export interface displayType {
name: string;
logo: logoType;
language: string;
}
export interface issuerType {
credential_issuer: string;
protocol: string;
client_id: string;
'.well-known': string;
redirect_uri: string;
scopes_supported: [string];
additional_headers: object;
authorization_endpoint: string;
token_endpoint: string;
credential_endpoint: string;
credential_audience: string;
display: [displayType];
}

View File

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

View File

@@ -7,7 +7,7 @@ import {log, respond} from 'xstate/lib/actions';
import {ExistingMosipVCItemEvents} from './VCItemMachine/ExistingMosipVCItem/ExistingMosipVCItemMachine';
import {MY_VCS_STORE_KEY, RECEIVED_VCS_STORE_KEY} from '../shared/constants';
import {parseMetadatas, VCMetadata} from '../shared/VCMetadata';
import {OpenId4VCIProtocol} from '../shared/openId4VCI/Utils';
import {Protocols} from '../shared/openId4VCI/Utils';
import {EsignetMosipVCItemEvents} from './VCItemMachine/EsignetMosipVCItem/EsignetMosipVCItemMachine';
import {ActivityLogEvents} from './activityLog';
import {ActivityLog} from '../components/ActivityLogEvent';
@@ -251,7 +251,7 @@ export const vcMachine =
getVcItemResponse: respond((context, event) => {
const vc = context.vcs[event.vcMetadata?.getVcKey()];
if (event.protocol === OpenId4VCIProtocol) {
if (event.protocol === Protocols.OpenId4VCI) {
return EsignetMosipVCItemEvents.GET_VC_RESPONSE(vc);
}
return ExistingMosipVCItemEvents.GET_VC_RESPONSE(vc);

View File

@@ -11,7 +11,6 @@ import {TabRef} from './HomeScreenMachine';
import {useTranslation} from 'react-i18next';
import {ActorRefFrom} from 'xstate';
import {ExistingMosipVCItemMachine} from '../../machines/VCItemMachine/ExistingMosipVCItem/ExistingMosipVCItemMachine';
import {isOpenId4VCIEnabled} from '../../shared/openId4VCI/Utils';
import LinearGradient from 'react-native-linear-gradient';
import {EsignetMosipVCItemMachine} from '../../machines/VCItemMachine/EsignetMosipVCItem/EsignetMosipVCItemMachine';
import {ErrorMessageOverlay} from '../../components/MessageOverlay';
@@ -76,7 +75,7 @@ export const HomeScreen: React.FC<HomeRouteProps> = props => {
</Column>
)}
</Column>
{isOpenId4VCIEnabled() && <DownloadFABIcon />}
<DownloadFABIcon />
<ErrorMessageOverlay
translationPath={'MyVcsTab'}
isVisible={controller.isMinimumStorageLimitReached}

View File

@@ -13,7 +13,6 @@ import {
MessageOverlay,
} from '../../components/MessageOverlay';
import {groupBy} from '../../shared/javascript';
import {isOpenId4VCIEnabled} from '../../shared/openId4VCI/Utils';
import {VcItemContainer} from '../../components/VC/VcItemContainer';
import {BannerNotification} from '../../components/BannerNotification';
import {
@@ -49,14 +48,6 @@ export const MyVcsTab: React.FC<HomeScreenTabProps> = props => {
GET_INDIVIDUAL_ID({id: '', idType: 'UIN'});
};
const onPressHandler = () => {
sendStartEvent(getStartEventData('VC Download', {id: 'UIN, VID, AID'}));
sendInteractEvent(
getInteractEventData('VC Download', 'CLICK', `Download VC Button`),
);
controller.DOWNLOAD_ID();
};
useEffect(() => {
if (controller.areAllVcsLoaded) {
controller.RESET_STORE_VC_ITEM_STATUS();
@@ -134,15 +125,6 @@ export const MyVcsTab: React.FC<HomeScreenTabProps> = props => {
);
})}
</Column>
{!isOpenId4VCIEnabled() && (
<Button
testID="downloadCard"
type="gradient"
disabled={controller.isRefreshingVcs}
title={t('downloadCard')}
onPress={onPressHandler}
/>
)}
</React.Fragment>
)}
{controller.vcMetadatas.length === 0 && (
@@ -157,34 +139,13 @@ export const MyVcsTab: React.FC<HomeScreenTabProps> = props => {
lineHeight={1}>
{t('bringYourDigitalID')}
</Text>
{isOpenId4VCIEnabled() && (
<Text
style={Theme.TextStyles.bold}
color={Theme.Colors.textLabel}
align="center"
margin="0 12 30 12">
{t('generateVcFABDescription')}
</Text>
)}
{!isOpenId4VCIEnabled() && (
<React.Fragment>
<Text
style={Theme.TextStyles.bold}
color={Theme.Colors.textLabel}
align="center"
margin="0 12 30 12">
{t('generateVcDescription')}
</Text>
<Button
testID="downloadCard"
type="gradient"
disabled={controller.isRefreshingVcs}
title={t('downloadCard')}
onPress={onPressHandler}
/>
</React.Fragment>
)}
<Text
style={Theme.TextStyles.bold}
color={Theme.Colors.textLabel}
align="center"
margin="0 12 30 12">
{t('generateVcFABDescription')}
</Text>
</Column>
</React.Fragment>
)}
@@ -227,12 +188,6 @@ export const MyVcsTab: React.FC<HomeScreenTabProps> = props => {
title={controller.walletBindingError}
onButtonPress={controller.DISMISS}
/>
<ErrorMessageOverlay
translationPath={'MyVcsTab'}
isVisible={controller.isMinimumStorageLimitReached}
error={'errors.storageLimitReached'}
onDismiss={controller.DISMISS}
/>
<MessageOverlay
isVisible={controller.isTampered}
title={t('errors.vcIsTampered.title')}

View File

@@ -26,7 +26,6 @@ import {
selectIsRequestSuccessful,
selectGetVcModal,
selectIsSavingFailedInIdle,
selectIsMinimumStorageLimitReached,
selectIsNetworkOff,
} from './MyVcsTabMachine';
import {
@@ -54,10 +53,6 @@ export function useMyVcsTab(props: HomeScreenTabProps) {
walletBindingError: useSelector(service, selectWalletBindingError),
isBindingError: useSelector(service, selectShowWalletBindingError),
isBindingSuccess: useSelector(vcService, selectWalletBindingSuccess),
isMinimumStorageLimitReached: useSelector(
service,
selectIsMinimumStorageLimitReached,
),
isNetworkOff: useSelector(service, selectIsNetworkOff),
showHardwareKeystoreNotExistsAlert: useSelector(
settingsService,

View File

@@ -15,7 +15,6 @@ import {AppServices} from '../../shared/GlobalContext';
import {MY_VCS_STORE_KEY} from '../../shared/constants';
import {AddVcModalMachine} from './MyVcs/AddVcModalMachine';
import {GetVcModalMachine} from './MyVcs/GetVcModalMachine';
import Storage from '../../shared/storage';
import {VCMetadata} from '../../shared/VCMetadata';
import {EsignetMosipVCItemMachine} from '../../machines/VCItemMachine/EsignetMosipVCItem/EsignetMosipVCItemMachine';
import NetInfo from '@react-native-community/netinfo';
@@ -75,7 +74,7 @@ export const MyVcsTabMachine = model.createMachine(
onDone: [
{
cond: 'isNetworkOn',
target: 'checkStorage',
target: '#MyVcsTab.addingVc',
},
{
target: 'networkOff',
@@ -83,26 +82,6 @@ export const MyVcsTabMachine = model.createMachine(
],
},
},
checkStorage: {
invoke: {
src: 'checkStorageAvailability',
onDone: [
{
cond: 'isMinimumStorageLimitReached',
target: 'storageLimitReached',
},
{
target: '#MyVcsTab.addingVc',
},
],
},
},
storageLimitReached: {
on: {
DISMISS: '#idle',
},
},
networkOff: {
on: {
DISMISS: '#idle',
@@ -188,11 +167,6 @@ export const MyVcsTabMachine = model.createMachine(
},
{
services: {
checkStorageAvailability: () => async () => {
return Promise.resolve(
Storage.isMinimumLimitReached('minStorageRequired'),
);
},
checkNetworkStatus: async () => {
const state = await NetInfo.fetch();
return state.isConnected;
@@ -231,7 +205,6 @@ export const MyVcsTabMachine = model.createMachine(
},
guards: {
isMinimumStorageLimitReached: (_context, event) => Boolean(event.data),
isNetworkOn: (_context, event) => Boolean(event.data),
},
},
@@ -262,9 +235,6 @@ export function selectIsSavingFailedInIdle(state: State) {
return state.matches('addingVc.savingFailed.idle');
}
export function selectIsMinimumStorageLimitReached(state: State) {
return state.matches('addVc.storageLimitReached');
}
export function selectIsNetworkOff(state: State) {
return state.matches('addVc.networkOff');
}

View File

@@ -1,75 +1,44 @@
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'done.invoke.AddVcModal': {
type: 'done.invoke.AddVcModal';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.GetVcModal': {
type: 'done.invoke.GetVcModal';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'done.invoke.MyVcsTab.addVc.checkStorage:invocation[0]': {
type: 'done.invoke.MyVcsTab.addVc.checkStorage:invocation[0]';
data: unknown;
__tip: 'See the XState TS docs to learn how to strongly type this.';
};
'xstate.init': {type: 'xstate.init'};
};
invokeSrcNameMap: {
checkStorageAvailability: 'done.invoke.MyVcsTab.addVc.checkStorage:invocation[0]';
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
refreshMyVc: 'IS_TAMPERED';
resetIsTampered: 'IS_TAMPERED';
resetStoringVcItemStatus: 'RESET_STORE_VC_ITEM_STATUS';
sendVcAdded: 'STORE_RESPONSE';
setStoringVcItemStatus: 'SET_STORE_VC_ITEM_STATUS' | 'STORE_RESPONSE';
storeVcItem: 'done.invoke.AddVcModal';
viewVcFromParent: 'VIEW_VC';
};
eventsCausingDelays: {};
eventsCausingGuards: {
isMinimumStorageLimitReached: 'done.invoke.MyVcsTab.addVc.checkStorage:invocation[0]';
};
eventsCausingServices: {
AddVcModal:
| 'done.invoke.GetVcModal'
| 'done.invoke.MyVcsTab.addVc.checkStorage:invocation[0]';
GetVcModal: 'GET_VC';
checkStorageAvailability: 'ADD_VC';
};
matchesStates:
| 'addVc'
| 'addVc.checkStorage'
| 'addVc.storageLimitReached'
| 'addingVc'
| 'addingVc.savingFailed'
| 'addingVc.savingFailed.idle'
| 'addingVc.storing'
| 'addingVc.waitingForvcKey'
| 'gettingVc'
| 'gettingVc.waitingForvcKey'
| 'idle'
| 'viewingVc'
| {
addVc?: 'checkStorage' | 'storageLimitReached';
addingVc?:
| 'savingFailed'
| 'storing'
| 'waitingForvcKey'
| {savingFailed?: 'idle'};
gettingVc?: 'waitingForvcKey';
};
tags: never;
}
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
"done.invoke.AddVcModal": { type: "done.invoke.AddVcModal"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.GetVcModal": { type: "done.invoke.GetVcModal"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]": { type: "done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]"; data: unknown; __tip: "See the XState TS docs to learn how to strongly type this." };
"xstate.init": { type: "xstate.init" };
};
invokeSrcNameMap: {
"checkNetworkStatus": "done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]";
};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {
"resetStoringVcItemStatus": "RESET_STORE_VC_ITEM_STATUS";
"sendVcAdded": "STORE_RESPONSE";
"setStoringVcItemStatus": "SET_STORE_VC_ITEM_STATUS" | "STORE_RESPONSE";
"storeVcItem": "done.invoke.AddVcModal";
"viewVcFromParent": "VIEW_VC";
};
eventsCausingDelays: {
};
eventsCausingGuards: {
"isNetworkOn": "done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]";
};
eventsCausingServices: {
"AddVcModal": "done.invoke.GetVcModal" | "done.invoke.MyVcsTab.addVc.checkNetwork:invocation[0]";
"GetVcModal": "GET_VC";
"checkNetworkStatus": "ADD_VC" | "TRY_AGAIN";
};
matchesStates: "addVc" | "addVc.checkNetwork" | "addVc.networkOff" | "addingVc" | "addingVc.savingFailed" | "addingVc.savingFailed.idle" | "addingVc.storing" | "addingVc.waitingForvcKey" | "gettingVc" | "gettingVc.waitingForvcKey" | "idle" | "viewingVc" | { "addVc"?: "checkNetwork" | "networkOff";
"addingVc"?: "savingFailed" | "storing" | "waitingForvcKey" | { "savingFailed"?: "idle"; };
"gettingVc"?: "waitingForvcKey"; };
tags: never;
}

View File

@@ -11,7 +11,11 @@ import {HomeRouteProps} from '../../routes/main';
import {useIssuerScreenController} from './IssuerScreenController';
import {Loader} from '../../components/ui/Loader';
import testIDProps, {removeWhiteSpace} from '../../shared/commonUtil';
import {ErrorMessage} from '../../shared/openId4VCI/Utils';
import {
ErrorMessage,
getDisplayObjectForCurrentLanguage,
Protocols,
} from '../../shared/openId4VCI/Utils';
import {
getInteractEventData,
getStartEventData,
@@ -52,16 +56,14 @@ export const IssuersScreen: React.FC<
controller.isStoring,
]);
const onPressHandler = (id: string) => {
const onPressHandler = (id: string, protocol: string) => {
sendStartEvent(getStartEventData('VC Download', {id: id}));
sendInteractEvent(
getInteractEventData('VC Download', 'CLICK', `IssuerType: ${id}`),
);
if (id !== 'UIN, VID, AID') {
controller.SELECTED_ISSUER(id);
} else {
controller.DOWNLOAD_ID();
}
protocol === Protocols.OTP
? controller.DOWNLOAD_ID()
: controller.SELECTED_ISSUER(id);
};
const isGenericError = () => {
@@ -139,15 +141,21 @@ export const IssuersScreen: React.FC<
{controller.issuers.length > 0 && (
<FlatList
data={controller.issuers}
scrollEnabled={false}
renderItem={({item}) => (
<Issuer
testID={removeWhiteSpace(item.id)}
key={item.id}
id={item.id}
displayName={item.displayName}
logoUrl={item.logoUrl}
onPress={() => onPressHandler(item.id)}
testID={removeWhiteSpace(item.credential_issuer)}
key={item.credential_issuer}
id={item.credential_issuer}
displayName={
getDisplayObjectForCurrentLanguage(item.display)?.name
}
logoUrl={
getDisplayObjectForCurrentLanguage(item.display)?.logo
?.url
}
onPress={() =>
onPressHandler(item.credential_issuer, item.protocol)
}
{...props}
/>
)}

View File

@@ -1,4 +1,5 @@
import {VC, VcIdType} from '../types/VC/ExistingMosipVC/vc';
import {Protocols} from './openId4VCI/Utils';
const VC_KEY_PREFIX = 'VC';
const VC_ITEM_STORE_KEY_REGEX = '^VC_[a-zA-Z0-9_-]+$';
@@ -57,7 +58,7 @@ export class VCMetadata {
}
isFromOpenId4VCI() {
return this.protocol !== '' && this.issuer !== '';
return this.protocol === Protocols.OpenId4VCI;
}
// Used for mmkv storage purposes and as a key for components and vc maps

View File

@@ -21,16 +21,11 @@ export const API_URLS = {
export const API = {
fetchIssuers: async () => {
const defaultIssuer = {
id: 'UIN, VID, AID',
displayName: 'UIN, VID, AID',
};
const response = await request(
API_URLS.issuersList.method,
API_URLS.issuersList.buildURL(),
);
return [defaultIssuer, ...(response.response.issuers || [])];
return response.response.issuers || [];
},
fetchIssuerConfig: async (issuerId: string) => {

View File

@@ -25,5 +25,5 @@ export default function testIDProps(id) {
}
export const removeWhiteSpace = (str: string) => {
return str.replace(/\s/g, '');
return str ? str.replace(/\s/g, '') : str;
};

View File

@@ -3,19 +3,25 @@ import jwtDecode from 'jwt-decode';
import jose from 'node-jose';
import {isIOS} from '../constants';
import pem2jwk from 'simple-pem2jwk';
import {Issuers_Key_Ref} from '../../machines/issuersMachine';
import {ENABLE_OPENID_FOR_VC} from 'react-native-dotenv';
import {
displayType,
Issuers_Key_Ref,
issuerType,
} from '../../machines/issuersMachine';
import getAllConfigurations from '../commonprops/commonProps';
import {CredentialWrapper} from '../../types/VC/EsignetMosipVC/vc';
import {VCMetadata} from '../VCMetadata';
import i18next from 'i18next';
export const OpenId4VCIProtocol = 'OpenId4VCIProtocol';
export const isOpenId4VCIEnabled = () => {
return ENABLE_OPENID_FOR_VC === 'true';
export const Protocols = {
OpenId4VCI: 'OpenId4VCI',
OTP: 'OTP',
};
export const getIdentifier = (context, credential) => {
const credId = credential.credential.id.split('/');
return (
context.selectedIssuer.id +
context.selectedIssuer.credential_issuer +
':' +
context.selectedIssuer.protocol +
':' +
@@ -38,6 +44,56 @@ export const getBody = async context => {
};
};
export const updateCredentialInformation = (context, credential) => {
let credentialWrapper: CredentialWrapper = {};
credentialWrapper.verifiableCredential = credential;
credentialWrapper.identifier = getIdentifier(context, credential);
credentialWrapper.generatedOn = new Date();
credentialWrapper.verifiableCredential.issuerLogo =
getDisplayObjectForCurrentLanguage(context.selectedIssuer.display)?.logo;
return credentialWrapper;
};
export const getDisplayObjectForCurrentLanguage = (
display: [displayType],
): displayType => {
const currentLanguage = i18next.language;
let displayType = display.filter(obj => obj.language == currentLanguage)[0];
if (!displayType) {
displayType = display.filter(obj => obj.language == 'en')[0];
}
return displayType;
};
export const getVCMetadata = context => {
const [issuer, protocol, requestId] =
context.credentialWrapper?.identifier.split(':');
return VCMetadata.fromVC({
requestId: requestId ? requestId : null,
issuer: issuer,
protocol: protocol,
id: context.verifiableCredential?.credential.credentialSubject.UIN
? context.verifiableCredential?.credential.credentialSubject.UIN
: context.verifiableCredential?.credential.credentialSubject.VID,
});
};
export const constructAuthorizationConfiguration = (
selectedIssuer: issuerType,
) => {
return {
clientId: selectedIssuer.client_id,
scopes: selectedIssuer.scopes_supported,
additionalHeaders: selectedIssuer.additional_headers,
wellKnownEndpoint: selectedIssuer['.well-known'],
redirectUrl: selectedIssuer.redirect_uri,
serviceConfiguration: {
authorizationEndpoint: selectedIssuer.authorization_endpoint,
tokenEndpoint: selectedIssuer.token_endpoint,
},
};
};
export const getJWK = async publicKey => {
try {
let publicKeyJWKString;
@@ -74,9 +130,9 @@ export const getJWT = async context => {
const decodedToken = jwtDecode(context.tokenResponse.accessToken);
const payload64 = encodeB64(
JSON.stringify({
iss: context.selectedIssuer.clientId,
iss: context.selectedIssuer.client_id,
nonce: decodedToken.c_nonce,
aud: context.selectedIssuer.serviceConfiguration.credentialAudience,
aud: context.selectedIssuer.credential_audience,
iat: Math.floor(new Date().getTime() / 1000),
exp: Math.floor(new Date().getTime() / 1000) + 18000,
}),

View File

@@ -16,7 +16,7 @@ export class BackendResponseError extends Error {
export async function request(
method: HTTP_METHOD,
path: `/${string}`,
path: `/${string}` | string,
body?: Record<string, unknown>,
host = MIMOTO_BASE_URL,
headers: Record<string, string> = {

View File

@@ -1,4 +1,5 @@
import {WalletBindingResponse} from '../../../shared/cryptoutil/cryptoUtil';
import {logoType} from '../../../machines/issuersMachine';
export interface VC {
id?: string;
@@ -68,7 +69,7 @@ export interface Credential {
}
export interface VerifiableCredential {
issuerLogo: string;
issuerLogo: logoType;
format: string;
credential: Credential;
}