mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 05:27:57 -05:00
[INJI-609]: Dynamic VC Render (#1140)
* [INJI-609]: render vc claims dynamically using feature toggle Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> * [INJI-609]: remove unwanted snippet Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> * [INJI-609]: add tooltip and ellipsis for longer text Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> * [INJI-609]: add tooltip and ellipsis for longer text 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:
7
.env
7
.env
@@ -2,9 +2,9 @@
|
||||
# eg . npm build android:newlogic --reset-cache
|
||||
|
||||
#MIMOTO_HOST=http://mock.mimoto.newlogic.dev
|
||||
MIMOTO_HOST=https://api.qa-inji.mosip.net
|
||||
MIMOTO_HOST=https://api.qa-inji1.mosip.net
|
||||
|
||||
ESIGNET_HOST=https://api.qa-inji.mosip.net
|
||||
ESIGNET_HOST=https://api.qa-inji1.mosip.net
|
||||
|
||||
OBSRV_HOST = https://dataset-api.obsrv.mosip.net
|
||||
|
||||
@@ -17,3 +17,6 @@ DEBUG_MODE=false
|
||||
|
||||
#supported languages( en, fil, ar, hi, kn, ta)
|
||||
APPLICATION_LANGUAGE=en
|
||||
|
||||
#Card Templatization - Render Claims Dynamically.
|
||||
CARD_TEMPLATIZATION=false
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from 'react';
|
||||
import {useTranslation} from 'react-i18next';
|
||||
import {Dimensions} from 'react-native';
|
||||
import {Icon} from 'react-native-elements';
|
||||
import {VerifiableCredential} from '../../../types/VC/ExistingMosipVC/vc';
|
||||
import {Row, Text} from '../../ui';
|
||||
import {Theme} from '../../ui/styleUtils';
|
||||
import {View} from 'react-native';
|
||||
|
||||
const WalletUnverifiedIcon: React.FC = () => {
|
||||
return (
|
||||
@@ -41,17 +41,21 @@ const WalletUnverifiedActivationDetails: React.FC<
|
||||
const {t} = useTranslation('VcDetails');
|
||||
return (
|
||||
<Row style={Theme.Styles.vcActivationDetailsWrapper}>
|
||||
{props.verifiableCredential && <WalletUnverifiedIcon />}
|
||||
<Text
|
||||
color={Theme.Colors.Details}
|
||||
testID="activationPending"
|
||||
weight="regular"
|
||||
style={
|
||||
!props.verifiableCredential
|
||||
? Theme.Styles.loadingTitle
|
||||
: Theme.Styles.statusLabel
|
||||
}
|
||||
children={t('offlineAuthDisabledHeader')}></Text>
|
||||
<View style={{flex: 1, alignSelf: 'center', justifyContent: 'center'}}>
|
||||
{props.verifiableCredential && <WalletUnverifiedIcon />}
|
||||
</View>
|
||||
<View style={{flex: 4}}>
|
||||
<Text
|
||||
color={Theme.Colors.Details}
|
||||
testID="activationPending"
|
||||
weight="regular"
|
||||
style={
|
||||
!props.verifiableCredential
|
||||
? Theme.Styles.loadingTitle
|
||||
: Theme.Styles.statusLabel
|
||||
}
|
||||
children={t('offlineAuthDisabledHeader')}></Text>
|
||||
</View>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
@@ -62,19 +66,23 @@ const WalletVerifiedActivationDetails: React.FC<
|
||||
const {t} = useTranslation('WalletBinding');
|
||||
return (
|
||||
<Row style={Theme.Styles.vcActivationDetailsWrapper}>
|
||||
<WalletVerifiedIcon />
|
||||
<Text
|
||||
color={Theme.Colors.statusLabel}
|
||||
testID="activated"
|
||||
weight="regular"
|
||||
size="smaller"
|
||||
margin="0 0 0 5"
|
||||
style={
|
||||
!props.verifiableCredential
|
||||
? Theme.Styles.loadingTitle
|
||||
: Theme.Styles.statusLabel
|
||||
}
|
||||
children={t('profileAuthenticated')}></Text>
|
||||
<View style={{flex: 1, alignSelf: 'center', justifyContent: 'center'}}>
|
||||
<WalletVerifiedIcon />
|
||||
</View>
|
||||
<View style={{flex: 4}}>
|
||||
<Text
|
||||
color={Theme.Colors.statusLabel}
|
||||
testID="activated"
|
||||
weight="regular"
|
||||
size="smaller"
|
||||
margin="0 0 0 5"
|
||||
style={
|
||||
!props.verifiableCredential
|
||||
? Theme.Styles.loadingTitle
|
||||
: Theme.Styles.statusLabel
|
||||
}
|
||||
children={t('profileAuthenticated')}></Text>
|
||||
</View>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
MosipVCItemDetails,
|
||||
ExistingMosipVCItemDetailsProps,
|
||||
EsignetMosipVCItemDetailsProps,
|
||||
ExistingMosipVCItemDetailsProps,
|
||||
MosipVCItemDetails,
|
||||
} from './MosipVCItem/MosipVCItemDetails';
|
||||
|
||||
import {CARD_TEMPLATIZATION} from 'react-native-dotenv';
|
||||
import {VCDetailView} from './Views/VCDetailView';
|
||||
|
||||
export const VcDetailsContainer: React.FC<
|
||||
ExistingMosipVCItemDetailsProps | EsignetMosipVCItemDetailsProps
|
||||
> = props => {
|
||||
if (CARD_TEMPLATIZATION === 'true') return <VCDetailView {...props} />;
|
||||
return <MosipVCItemDetails {...props} />;
|
||||
};
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
EsignetMosipVCItemProps,
|
||||
MosipVCItem,
|
||||
ExistingMosipVCItemProps,
|
||||
MosipVCItem,
|
||||
} from './MosipVCItem/MosipVCItem';
|
||||
import {CARD_TEMPLATIZATION} from 'react-native-dotenv';
|
||||
import {VCCardView} from './Views/VCCardView';
|
||||
|
||||
export const VcItemContainer: React.FC<
|
||||
ExistingMosipVCItemProps | EsignetMosipVCItemProps
|
||||
> = props => {
|
||||
if (CARD_TEMPLATIZATION === 'true') return <VCCardView {...props} />;
|
||||
return <MosipVCItem {...props} />;
|
||||
};
|
||||
|
||||
166
components/VC/Views/VCCardView.tsx
Normal file
166
components/VC/Views/VCCardView.tsx
Normal file
@@ -0,0 +1,166 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {Pressable, View} from 'react-native';
|
||||
import {ActorRefFrom} from 'xstate';
|
||||
import {
|
||||
ExistingMosipVCItemEvents,
|
||||
ExistingMosipVCItemMachine,
|
||||
} from '../../../machines/VCItemMachine/ExistingMosipVCItem/ExistingMosipVCItemMachine';
|
||||
import {ErrorMessageOverlay} from '../../MessageOverlay';
|
||||
import {Theme} from '../../ui/styleUtils';
|
||||
import {Row} from '../../ui';
|
||||
import {KebabPopUp} from '../../KebabPopUp';
|
||||
import {VCMetadata} from '../../../shared/VCMetadata';
|
||||
import {format} from 'date-fns';
|
||||
import {EsignetMosipVCItemMachine} from '../../../machines/VCItemMachine/EsignetMosipVCItem/EsignetMosipVCItemMachine';
|
||||
|
||||
import {VCCardSkeleton} from '../common/VCCardSkeleton';
|
||||
import {VCCardViewContent} from './VCCardViewContent';
|
||||
import {MosipVCItemActivationStatus} from '../MosipVCItem/MosipVCItemActivationStatus';
|
||||
import {useVcItemController} from '../MosipVCItem/VcItemController';
|
||||
import {getCredentialIssuersWellKnownConfig} from '../../../shared/openId4VCI/Utils';
|
||||
import {
|
||||
CARD_VIEW_ADD_ON_FIELDS,
|
||||
CARD_VIEW_DEFAULT_FIELDS,
|
||||
} from '../../../shared/constants';
|
||||
import {isVCLoaded} from '../common/VCUtils';
|
||||
|
||||
export const VCCardView: React.FC<
|
||||
ExistingMosipVCItemProps | EsignetMosipVCItemProps
|
||||
> = props => {
|
||||
let {
|
||||
service,
|
||||
context,
|
||||
verifiableCredential,
|
||||
emptyWalletBindingId,
|
||||
isKebabPopUp,
|
||||
isSavingFailedInIdle,
|
||||
storeErrorTranslationPath,
|
||||
generatedOn,
|
||||
|
||||
DISMISS,
|
||||
KEBAB_POPUP,
|
||||
} = useVcItemController(props);
|
||||
|
||||
let formattedDate =
|
||||
generatedOn && format(new Date(generatedOn), 'MM/dd/yyyy');
|
||||
|
||||
useEffect(() => {
|
||||
service.send(
|
||||
ExistingMosipVCItemEvents.UPDATE_VC_METADATA(props.vcMetadata),
|
||||
);
|
||||
}, [props.vcMetadata]);
|
||||
|
||||
const credential = props.isDownloading
|
||||
? null
|
||||
: props.vcMetadata.isFromOpenId4VCI()
|
||||
? verifiableCredential?.credential
|
||||
: verifiableCredential;
|
||||
|
||||
const [fields, setFields] = useState([]);
|
||||
const [wellknown, setWellknown] = useState(null);
|
||||
useEffect(() => {
|
||||
getCredentialIssuersWellKnownConfig(
|
||||
props?.vcMetadata.issuer,
|
||||
verifiableCredential?.wellKnown,
|
||||
CARD_VIEW_DEFAULT_FIELDS,
|
||||
).then(response => {
|
||||
setWellknown(response.wellknown);
|
||||
setFields(response.fields.slice(0, 1).concat(CARD_VIEW_ADD_ON_FIELDS));
|
||||
});
|
||||
}, [verifiableCredential?.wellKnown]);
|
||||
|
||||
if (!isVCLoaded(verifiableCredential, fields)) {
|
||||
return <VCCardSkeleton />;
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Pressable
|
||||
accessible={false}
|
||||
onPress={() => props.onPress(service)}
|
||||
disabled={!verifiableCredential}
|
||||
style={
|
||||
props.selected
|
||||
? Theme.Styles.selectedBindedVc
|
||||
: Theme.Styles.closeCardBgContainer
|
||||
}>
|
||||
<VCCardViewContent
|
||||
vcMetadata={props.vcMetadata}
|
||||
context={context}
|
||||
verifiableCredential={verifiableCredential}
|
||||
credential={credential}
|
||||
fields={fields}
|
||||
wellknown={wellknown}
|
||||
generatedOn={formattedDate}
|
||||
selectable={props.selectable}
|
||||
selected={props.selected}
|
||||
service={service}
|
||||
isPinned={props.isPinned}
|
||||
onPress={() => props.onPress(service)}
|
||||
isDownloading={props.isDownloading}
|
||||
/>
|
||||
<View style={Theme.Styles.horizontalLine} />
|
||||
{props.isSharingVc ? null : (
|
||||
<Row style={Theme.Styles.activationTab}>
|
||||
<MosipVCItemActivationStatus
|
||||
vcMetadata={props.vcMetadata}
|
||||
verifiableCredential={verifiableCredential}
|
||||
emptyWalletBindingId={emptyWalletBindingId}
|
||||
showOnlyBindedVc={props.showOnlyBindedVc}
|
||||
/>
|
||||
<Row style={Theme.Styles.verticalLineWrapper}>
|
||||
<View style={Theme.Styles.verticalLine} />
|
||||
</Row>
|
||||
<Row style={Theme.Styles.kebabIcon}>
|
||||
<Pressable
|
||||
onPress={KEBAB_POPUP}
|
||||
accessible={false}
|
||||
style={Theme.Styles.kebabPressableContainer}>
|
||||
<KebabPopUp
|
||||
vcMetadata={props.vcMetadata}
|
||||
iconName="dots-three-horizontal"
|
||||
iconType="entypo"
|
||||
isVisible={isKebabPopUp}
|
||||
onDismiss={DISMISS}
|
||||
service={service}
|
||||
/>
|
||||
</Pressable>
|
||||
</Row>
|
||||
</Row>
|
||||
)}
|
||||
</Pressable>
|
||||
<ErrorMessageOverlay
|
||||
isVisible={isSavingFailedInIdle}
|
||||
error={storeErrorTranslationPath}
|
||||
onDismiss={DISMISS}
|
||||
translationPath={'VcDetails'}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export interface ExistingMosipVCItemProps {
|
||||
vcMetadata: VCMetadata;
|
||||
margin?: string;
|
||||
selectable?: boolean;
|
||||
selected?: boolean;
|
||||
showOnlyBindedVc?: boolean;
|
||||
onPress?: (vcRef?: ActorRefFrom<typeof ExistingMosipVCItemMachine>) => void;
|
||||
onShow?: (vcRef?: ActorRefFrom<typeof ExistingMosipVCItemMachine>) => void;
|
||||
isSharingVc?: boolean;
|
||||
isDownloading?: boolean;
|
||||
isPinned?: boolean;
|
||||
}
|
||||
|
||||
export interface EsignetMosipVCItemProps {
|
||||
vcMetadata: VCMetadata;
|
||||
margin?: string;
|
||||
selectable?: boolean;
|
||||
selected?: boolean;
|
||||
showOnlyBindedVc?: boolean;
|
||||
onPress?: (vcRef?: ActorRefFrom<typeof EsignetMosipVCItemMachine>) => void;
|
||||
onShow?: (vcRef?: ActorRefFrom<typeof EsignetMosipVCItemMachine>) => void;
|
||||
isSharingVc?: boolean;
|
||||
isDownloading?: boolean;
|
||||
isPinned?: boolean;
|
||||
}
|
||||
132
components/VC/Views/VCCardViewContent.tsx
Normal file
132
components/VC/Views/VCCardViewContent.tsx
Normal file
@@ -0,0 +1,132 @@
|
||||
import React from 'react';
|
||||
import {ImageBackground} from 'react-native';
|
||||
import {VerifiableCredential} from '../../../types/VC/ExistingMosipVC/vc';
|
||||
import {Column, Row} from '../../ui';
|
||||
import {Theme} from '../../ui/styleUtils';
|
||||
import {CheckBox, Icon} from 'react-native-elements';
|
||||
import {SvgImage} from '../../ui/svg';
|
||||
import {
|
||||
fieldItemIterator,
|
||||
getIssuerLogo,
|
||||
isVCLoaded,
|
||||
setBackgroundColour,
|
||||
} from '../common/VCUtils';
|
||||
import VerifiedIcon from '../../VerifiedIcon';
|
||||
import {VCItemField} from '../common/VCItemField';
|
||||
import {useTranslation} from 'react-i18next';
|
||||
|
||||
export const VCCardViewContent: React.FC<
|
||||
ExistingMosipVCItemContentProps | EsignetMosipVCItemContentProps
|
||||
> = props => {
|
||||
const {t} = useTranslation('VcDetails');
|
||||
const selectableOrCheck = props.selectable ? (
|
||||
<CheckBox
|
||||
checked={props.selected}
|
||||
checkedIcon={
|
||||
<Icon name="check-circle" type="material" color={Theme.Colors.Icon} />
|
||||
}
|
||||
uncheckedIcon={
|
||||
<Icon
|
||||
name="radio-button-unchecked"
|
||||
color={Theme.Colors.uncheckedIcon}
|
||||
/>
|
||||
}
|
||||
onPress={() => props.onPress()}
|
||||
/>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<ImageBackground
|
||||
source={!props.credential ? null : Theme.CloseCard}
|
||||
resizeMode="stretch"
|
||||
style={[
|
||||
!props.credential
|
||||
? Theme.Styles.vertloadingContainer
|
||||
: Theme.Styles.backgroundImageContainer,
|
||||
setBackgroundColour(props.wellknown),
|
||||
]}>
|
||||
<Column>
|
||||
<Row align="space-between">
|
||||
<Row margin="5 0 0 5">
|
||||
{SvgImage.VcItemContainerProfileImage(props, props.credential)}
|
||||
<Column margin={'0 0 0 20'}>
|
||||
{fieldItemIterator(
|
||||
props.fields.slice(0, 2),
|
||||
props.credential,
|
||||
props.wellknown,
|
||||
props,
|
||||
)}
|
||||
</Column>
|
||||
</Row>
|
||||
<Column>{props.credential ? selectableOrCheck : null}</Column>
|
||||
</Row>
|
||||
{fieldItemIterator(
|
||||
props.fields.slice(2),
|
||||
props.credential,
|
||||
props.wellknown,
|
||||
props,
|
||||
)}
|
||||
<Row align={'space-between'} margin="0 8 5 8">
|
||||
<VCItemField
|
||||
key={'status'}
|
||||
fieldName={t('status')}
|
||||
fieldValue={
|
||||
!isVCLoaded(props.credential, props.fields) ? null : (
|
||||
<VerifiedIcon />
|
||||
)
|
||||
}
|
||||
wellknown={props.wellknown}
|
||||
verifiableCredential={props.credential}
|
||||
/>
|
||||
<Column
|
||||
testID="logo"
|
||||
style={{
|
||||
display: props.credential ? 'flex' : 'none',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}>
|
||||
{!isVCLoaded(props.credential, props.fields)
|
||||
? null
|
||||
: getIssuerLogo(
|
||||
props.vcMetadata.isFromOpenId4VCI(),
|
||||
props.verifiableCredential?.issuerLogo,
|
||||
)}
|
||||
</Column>
|
||||
</Row>
|
||||
</Column>
|
||||
</ImageBackground>
|
||||
);
|
||||
};
|
||||
|
||||
export interface ExistingMosipVCItemContentProps {
|
||||
context: any;
|
||||
verifiableCredential: VerifiableCredential;
|
||||
credential: VerifiableCredential;
|
||||
fields: [];
|
||||
wellknown: {};
|
||||
generatedOn: string;
|
||||
selectable: boolean;
|
||||
selected: boolean;
|
||||
isPinned?: boolean;
|
||||
service: any;
|
||||
onPress?: () => void;
|
||||
isDownloading?: boolean;
|
||||
}
|
||||
|
||||
export interface EsignetMosipVCItemContentProps {
|
||||
context: any;
|
||||
credential: VerifiableCredential;
|
||||
fields: [];
|
||||
wellknown: {};
|
||||
generatedOn: string;
|
||||
selectable: boolean;
|
||||
selected: boolean;
|
||||
isPinned?: boolean;
|
||||
service: any;
|
||||
onPress?: () => void;
|
||||
isDownloading?: boolean;
|
||||
}
|
||||
|
||||
VCCardViewContent.defaultProps = {
|
||||
isPinned: false,
|
||||
};
|
||||
248
components/VC/Views/VCDetailView.tsx
Normal file
248
components/VC/Views/VCDetailView.tsx
Normal file
@@ -0,0 +1,248 @@
|
||||
import {formatDistanceToNow} from 'date-fns';
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import * as DateFnsLocale from 'date-fns/locale';
|
||||
import {useTranslation} from 'react-i18next';
|
||||
import {Image, ImageBackground} from 'react-native';
|
||||
import {Icon} from 'react-native-elements';
|
||||
import {VC} from '../../../types/VC/ExistingMosipVC/vc';
|
||||
import {Button, Column, Row, Text} from '../../ui';
|
||||
import {Theme} from '../../ui/styleUtils';
|
||||
import {TextItem} from '../../ui/TextItem';
|
||||
import {QrCodeOverlay} from '../../QrCodeOverlay';
|
||||
import {VCMetadata} from '../../../shared/VCMetadata';
|
||||
import {
|
||||
VcIdType,
|
||||
VCSharingReason,
|
||||
VerifiableCredential,
|
||||
VerifiablePresentation,
|
||||
} from '../../../types/VC/EsignetMosipVC/vc';
|
||||
import {WalletBindingResponse} from '../../../shared/cryptoutil/cryptoUtil';
|
||||
import {logoType} from '../../../machines/issuersMachine';
|
||||
import {SvgImage} from '../../ui/svg';
|
||||
import {getCredentialIssuersWellKnownConfig} from '../../../shared/openId4VCI/Utils';
|
||||
import {
|
||||
DETAIL_VIEW_ADD_ON_FIELDS,
|
||||
DETAIL_VIEW_DEFAULT_FIELDS,
|
||||
} from '../../../shared/constants';
|
||||
import {
|
||||
fieldItemIterator,
|
||||
isVCLoaded,
|
||||
setBackgroundColour,
|
||||
} from '../common/VCUtils';
|
||||
import {ActivityIndicator} from '../../ui/ActivityIndicator';
|
||||
|
||||
const getIssuerLogo = (isOpenId4VCI: boolean, issuerLogo: logoType) => {
|
||||
if (isOpenId4VCI) {
|
||||
return (
|
||||
<Image
|
||||
src={issuerLogo?.url}
|
||||
alt={issuerLogo?.alt_text}
|
||||
style={Theme.Styles.issuerLogo}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return SvgImage.MosipLogo(Theme.Styles.vcDetailsLogo);
|
||||
};
|
||||
|
||||
const getProfileImage = (
|
||||
props: ExistingMosipVCItemDetailsProps | EsignetMosipVCItemDetailsProps,
|
||||
verifiableCredential,
|
||||
isOpenId4VCI,
|
||||
) => {
|
||||
if (isOpenId4VCI) {
|
||||
if (verifiableCredential?.credentialSubject.face) {
|
||||
return {uri: verifiableCredential?.credentialSubject.face};
|
||||
}
|
||||
} else {
|
||||
if (props.vc?.credential?.biometrics?.face) {
|
||||
return {uri: props.vc?.credential.biometrics.face};
|
||||
}
|
||||
}
|
||||
return <Icon name="person" color={Theme.Colors.Icon} size={88} />;
|
||||
};
|
||||
|
||||
export const VCDetailView: React.FC<
|
||||
ExistingMosipVCItemDetailsProps | EsignetMosipVCItemDetailsProps
|
||||
> = props => {
|
||||
const {t, i18n} = useTranslation('VcDetails');
|
||||
|
||||
let isOpenId4VCI = VCMetadata.fromVC(props.vc.vcMetadata).isFromOpenId4VCI();
|
||||
const issuerLogo = getIssuerLogo(
|
||||
isOpenId4VCI,
|
||||
props.vc?.verifiableCredential?.issuerLogo,
|
||||
);
|
||||
const verifiableCredential = isOpenId4VCI
|
||||
? props.vc?.verifiableCredential.credential
|
||||
: props.vc?.verifiableCredential;
|
||||
|
||||
let [fields, setFields] = useState([]);
|
||||
const [wellknown, setWellknown] = useState(null);
|
||||
useEffect(() => {
|
||||
getCredentialIssuersWellKnownConfig(
|
||||
VCMetadata.fromVC(props.vc.vcMetadata).issuer,
|
||||
props.vc?.verifiableCredential?.wellKnown,
|
||||
DETAIL_VIEW_DEFAULT_FIELDS,
|
||||
).then(response => {
|
||||
setWellknown(response.wellknown);
|
||||
setFields(response.fields.concat(DETAIL_VIEW_ADD_ON_FIELDS));
|
||||
});
|
||||
}, [props.verifiableCredential?.wellKnown]);
|
||||
|
||||
if (!isVCLoaded(verifiableCredential, fields)) {
|
||||
return <ActivityIndicator />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Column margin="10 4 10 4">
|
||||
<ImageBackground
|
||||
imageStyle={{width: '100%'}}
|
||||
resizeMethod="scale"
|
||||
resizeMode="stretch"
|
||||
style={[
|
||||
Theme.Styles.openCardBgContainer,
|
||||
setBackgroundColour(wellknown),
|
||||
]}
|
||||
source={Theme.OpenCard}>
|
||||
<Row padding="10" margin="0 10 0 8">
|
||||
<Column crossAlign="center">
|
||||
<Image
|
||||
source={getProfileImage(
|
||||
props,
|
||||
verifiableCredential,
|
||||
isOpenId4VCI,
|
||||
)}
|
||||
style={Theme.Styles.openCardImage}
|
||||
/>
|
||||
|
||||
<QrCodeOverlay qrCodeDetails={String(verifiableCredential)} />
|
||||
|
||||
<Column margin="20 0 0 0">{issuerLogo}</Column>
|
||||
</Column>
|
||||
<Column align="space-evenly" margin={'0 0 0 10'} style={{flex: 1}}>
|
||||
{fieldItemIterator(fields, verifiableCredential, wellknown, props)}
|
||||
</Column>
|
||||
</Row>
|
||||
</ImageBackground>
|
||||
|
||||
{props.vc?.reason?.length > 0 && (
|
||||
<Text
|
||||
testID="reasonForSharingTitle"
|
||||
margin="24 24 16 24"
|
||||
weight="semibold">
|
||||
{t('reasonForSharing')}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{props.vc?.reason?.map((reason, index) => (
|
||||
<TextItem
|
||||
testID="reason"
|
||||
key={index}
|
||||
divider
|
||||
label={formatDistanceToNow(reason.timestamp, {
|
||||
addSuffix: true,
|
||||
locale: DateFnsLocale[i18n.language],
|
||||
})}
|
||||
text={reason.message}
|
||||
/>
|
||||
))}
|
||||
|
||||
{props.activeTab !== 1 ? (
|
||||
props.isBindingPending ? (
|
||||
<Column style={Theme.Styles.openCardBgContainer} padding="10">
|
||||
<Column margin={'0 0 4 0'} crossAlign={'flex-start'}>
|
||||
<Icon
|
||||
name="shield-alert"
|
||||
color={Theme.Colors.Icon}
|
||||
size={Theme.ICON_LARGE_SIZE}
|
||||
type="material-community"
|
||||
containerStyle={{
|
||||
marginEnd: 5,
|
||||
bottom: 1,
|
||||
}}
|
||||
/>
|
||||
<Text
|
||||
testID="offlineAuthDisabledHeader"
|
||||
style={{flex: 1}}
|
||||
weight="semibold"
|
||||
size="small"
|
||||
margin={'5 0 0 0'}
|
||||
color={Theme.Colors.statusLabel}>
|
||||
{t('offlineAuthDisabledHeader')}
|
||||
</Text>
|
||||
</Column>
|
||||
<Text
|
||||
testID="offlineAuthDisabledMessage"
|
||||
style={{flex: 1, lineHeight: 17}}
|
||||
weight="regular"
|
||||
size="small"
|
||||
margin={'3 0 10 0'}
|
||||
color={Theme.Colors.statusMessage}>
|
||||
{t('offlineAuthDisabledMessage')}
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
testID="enableVerification"
|
||||
title={t('enableVerification')}
|
||||
onPress={props.onBinding}
|
||||
type="gradient"
|
||||
styles={{width: '100%'}}
|
||||
/>
|
||||
</Column>
|
||||
) : (
|
||||
<Column style={Theme.Styles.openCardBgContainer} padding="10">
|
||||
<Row crossAlign="center">
|
||||
<Icon
|
||||
name="verified-user"
|
||||
color={Theme.Colors.VerifiedIcon}
|
||||
size={28}
|
||||
containerStyle={{marginStart: 4, bottom: 1}}
|
||||
/>
|
||||
<Text
|
||||
testID="profileAuthenticated"
|
||||
numLines={1}
|
||||
color={Theme.Colors.statusLabel}
|
||||
weight="bold"
|
||||
size="smaller"
|
||||
margin="10 10 10 10"
|
||||
children={t('profileAuthenticated')}></Text>
|
||||
</Row>
|
||||
</Column>
|
||||
)
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Column>
|
||||
);
|
||||
};
|
||||
|
||||
export interface ExistingMosipVCItemDetailsProps {
|
||||
vc: VC;
|
||||
isBindingPending: boolean;
|
||||
onBinding?: () => void;
|
||||
activeTab?: Number;
|
||||
}
|
||||
|
||||
export interface EsignetMosipVCItemDetailsProps {
|
||||
vc: EsignetVC;
|
||||
isBindingPending: boolean;
|
||||
onBinding?: () => void;
|
||||
activeTab?: number;
|
||||
}
|
||||
|
||||
export interface EsignetVC {
|
||||
id: string;
|
||||
idType: VcIdType;
|
||||
verifiableCredential: VerifiableCredential;
|
||||
verifiablePresentation?: VerifiablePresentation;
|
||||
generatedOn: Date;
|
||||
requestId: string;
|
||||
isVerified: boolean;
|
||||
lastVerifiedOn: number;
|
||||
locked: boolean;
|
||||
reason?: VCSharingReason[];
|
||||
shouldVerifyPresence?: boolean;
|
||||
walletBindingResponse?: WalletBindingResponse;
|
||||
credentialRegistry: string;
|
||||
isPinned?: boolean;
|
||||
hashedId: string;
|
||||
}
|
||||
69
components/VC/common/VCCardInnerSkeleton.tsx
Normal file
69
components/VC/common/VCCardInnerSkeleton.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import {Theme} from '../../ui/styleUtils';
|
||||
import {Column, Row} from '../../ui';
|
||||
import {ImageBackground} from 'react-native';
|
||||
import {VCItemField} from './VCItemField';
|
||||
import React from 'react';
|
||||
import {SvgImage} from '../../ui/svg';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import ShimmerPlaceHolder from 'react-native-shimmer-placeholder';
|
||||
|
||||
export const VCCardInnerSkeleton = () => {
|
||||
return (
|
||||
<ImageBackground
|
||||
source={Theme.CloseCard}
|
||||
resizeMode="stretch"
|
||||
style={Theme.Styles.vertloadingContainer}>
|
||||
<Column>
|
||||
<Row margin={'0 20 10 10'}>
|
||||
<Column style={{marginTop: 10}}>
|
||||
{SvgImage.VcItemContainerProfileImage(undefined, null)}
|
||||
</Column>
|
||||
<Column margin={'0 0 0 20'}>
|
||||
{
|
||||
<>
|
||||
<VCItemField
|
||||
key={'empty1'}
|
||||
fieldName={'empty'}
|
||||
fieldValue={'empty'}
|
||||
verifiableCredential={null}
|
||||
wellknown={null}
|
||||
/>
|
||||
<VCItemField
|
||||
key={'empty2'}
|
||||
fieldName={'empty'}
|
||||
fieldValue={'empty'}
|
||||
verifiableCredential={null}
|
||||
wellknown={null}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
</Column>
|
||||
</Row>
|
||||
<Column margin="0 8 5 8">
|
||||
<VCItemField
|
||||
key={'empty3'}
|
||||
fieldName={'empty'}
|
||||
fieldValue={'empty'}
|
||||
verifiableCredential={null}
|
||||
wellknown={null}
|
||||
/>
|
||||
</Column>
|
||||
<Row align={'space-between'} margin="0 8 5 8">
|
||||
<VCItemField
|
||||
key={'empty4'}
|
||||
fieldName={'empty'}
|
||||
fieldValue={'empty'}
|
||||
verifiableCredential={null}
|
||||
wellknown={null}
|
||||
/>
|
||||
<ShimmerPlaceHolder
|
||||
LinearGradient={LinearGradient}
|
||||
width={60}
|
||||
height={60}
|
||||
style={{borderRadius: 5}}
|
||||
/>
|
||||
</Row>
|
||||
</Column>
|
||||
</ImageBackground>
|
||||
);
|
||||
};
|
||||
27
components/VC/common/VCCardSkeleton.tsx
Normal file
27
components/VC/common/VCCardSkeleton.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import {View} from 'react-native';
|
||||
import {Theme} from '../../ui/styleUtils';
|
||||
import {Row} from '../../ui';
|
||||
import React from 'react';
|
||||
import {VCCardInnerSkeleton} from './VCCardInnerSkeleton';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import ShimmerPlaceHolder from 'react-native-shimmer-placeholder';
|
||||
|
||||
export const VCCardSkeleton = () => {
|
||||
return (
|
||||
<View style={Theme.Styles.closeCardBgContainer}>
|
||||
<VCCardInnerSkeleton />
|
||||
<View style={Theme.Styles.horizontalLine} />
|
||||
<Row style={[Theme.Styles.activationTab, {height: 30, borderRadius: 20}]}>
|
||||
<Row style={Theme.Styles.vcActivationStatusContainer}>
|
||||
<Row style={Theme.Styles.vcActivationDetailsWrapper}>
|
||||
<ShimmerPlaceHolder
|
||||
LinearGradient={LinearGradient}
|
||||
width={300}
|
||||
style={{borderRadius: 5}}
|
||||
/>
|
||||
</Row>
|
||||
</Row>
|
||||
</Row>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
63
components/VC/common/VCItemField.tsx
Normal file
63
components/VC/common/VCItemField.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import {Column, Text} from '../../ui';
|
||||
import {Theme} from '../../ui/styleUtils';
|
||||
import React from 'react';
|
||||
import {setTextColor} from './VCUtils';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import ShimmerPlaceHolder from 'react-native-shimmer-placeholder';
|
||||
import {Tooltip} from 'react-native-elements';
|
||||
|
||||
export const VCItemField = ({
|
||||
verifiableCredential,
|
||||
fieldName,
|
||||
fieldValue,
|
||||
wellknown,
|
||||
}) => {
|
||||
if (!verifiableCredential) {
|
||||
return (
|
||||
<Column margin="9 0 0 0">
|
||||
<ShimmerPlaceHolder
|
||||
LinearGradient={LinearGradient}
|
||||
width={150}
|
||||
style={{marginBottom: 5, borderRadius: 5}}
|
||||
/>
|
||||
<ShimmerPlaceHolder
|
||||
LinearGradient={LinearGradient}
|
||||
width={180}
|
||||
style={{borderRadius: 5}}
|
||||
/>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Column margin="9 0 0 0">
|
||||
<Text
|
||||
testID={`${fieldName}Title`}
|
||||
weight="regular"
|
||||
size="smaller"
|
||||
{...setTextColor(wellknown)}
|
||||
style={[Theme.Styles.subtitle]}>
|
||||
{fieldName}
|
||||
</Text>
|
||||
<Tooltip
|
||||
toggleOnPress={fieldValue.length > 20}
|
||||
containerStyle={{
|
||||
width: 200,
|
||||
height: null,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
skipAndroidStatusBar={true}
|
||||
backgroundColor={Theme.Colors.Icon}
|
||||
popover={<Text>{fieldValue}</Text>}>
|
||||
<Text
|
||||
testID={`${fieldName}Value`}
|
||||
weight="semibold"
|
||||
numLines={1}
|
||||
ellipsizeMode={'tail'}
|
||||
style={[Theme.Styles.subtitle, setTextColor(wellknown)]}>
|
||||
{fieldValue}
|
||||
</Text>
|
||||
</Tooltip>
|
||||
</Column>
|
||||
);
|
||||
};
|
||||
159
components/VC/common/VCUtils.tsx
Normal file
159
components/VC/common/VCUtils.tsx
Normal file
@@ -0,0 +1,159 @@
|
||||
import {
|
||||
CredentialSubject,
|
||||
VerifiableCredential,
|
||||
} from '../../../types/VC/ExistingMosipVC/vc';
|
||||
import VerifiedIcon from '../../VerifiedIcon';
|
||||
import i18n, {getLocalizedField} from '../../../i18n';
|
||||
import {Row} from '../../ui';
|
||||
import {VCItemField} from './VCItemField';
|
||||
import React from 'react';
|
||||
import {format, parse} from 'date-fns';
|
||||
import {logoType} from '../../../machines/issuersMachine';
|
||||
import {Image} from 'react-native';
|
||||
import {Theme} from '../../ui/styleUtils';
|
||||
import {SvgImage} from '../../ui/svg';
|
||||
import {CREDENTIAL_REGISTRY_EDIT} from 'react-native-dotenv';
|
||||
|
||||
export const getFieldValue = (
|
||||
verifiableCredential: VerifiableCredential,
|
||||
field: string,
|
||||
props: any,
|
||||
) => {
|
||||
switch (field) {
|
||||
case 'status':
|
||||
return <VerifiedIcon />;
|
||||
case 'idType':
|
||||
return i18n.t('VcDetails:nationalCard');
|
||||
case 'dateOfBirth':
|
||||
return formattedDateOfBirth(verifiableCredential);
|
||||
case 'credentialRegistry':
|
||||
return props?.vc?.credentialRegistry;
|
||||
case 'address':
|
||||
return getLocalizedField(
|
||||
getFullAddress(verifiableCredential?.credentialSubject),
|
||||
);
|
||||
default:
|
||||
return getLocalizedField(verifiableCredential?.credentialSubject[field]);
|
||||
}
|
||||
};
|
||||
|
||||
export const getFieldName = (field: string, wellknown: any) => {
|
||||
if (wellknown && wellknown.credentials_supported) {
|
||||
const fieldObj =
|
||||
wellknown.credentials_supported[0].credential_definition
|
||||
.credentialSubject[field];
|
||||
if (fieldObj) {
|
||||
const newFieldObj = fieldObj.display.map(obj => {
|
||||
return {language: obj.locale, value: obj.name};
|
||||
});
|
||||
return getLocalizedField(newFieldObj);
|
||||
}
|
||||
}
|
||||
return i18n.t(`VcDetails:${field}`);
|
||||
};
|
||||
|
||||
export const setBackgroundColour = (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,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const setTextColor = (wellknown: any) => {
|
||||
if (wellknown && wellknown.credentials_supported[0]?.display) {
|
||||
return {
|
||||
color: wellknown.credentials_supported[0].display[0]?.text_color
|
||||
? wellknown.credentials_supported[0].display[0].text_color
|
||||
: Theme.Colors.textValue,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
function getFullAddress(credential: CredentialSubject) {
|
||||
if (!credential) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const fields = [
|
||||
'addressLine1',
|
||||
'addressLine2',
|
||||
'addressLine3',
|
||||
'city',
|
||||
'province',
|
||||
'region',
|
||||
];
|
||||
|
||||
return fields
|
||||
.map(field => getLocalizedField(credential[field]))
|
||||
.concat(credential.postalCode)
|
||||
.filter(Boolean)
|
||||
.join(', ');
|
||||
}
|
||||
|
||||
function formattedDateOfBirth(verifiableCredential: any) {
|
||||
const dateOfBirth = verifiableCredential?.credentialSubject.dateOfBirth;
|
||||
if (dateOfBirth) {
|
||||
const formatString =
|
||||
dateOfBirth.split('/').length === 1 ? 'yyyy' : 'yyyy/MM/dd';
|
||||
const parsedDate = parse(dateOfBirth, formatString, new Date());
|
||||
return format(parsedDate, 'MM/dd/yyyy');
|
||||
}
|
||||
return dateOfBirth;
|
||||
}
|
||||
|
||||
export const fieldItemIterator = (
|
||||
fields: any[],
|
||||
verifiableCredential: any,
|
||||
wellknown: any,
|
||||
props: any,
|
||||
) => {
|
||||
return fields.map(field => {
|
||||
const fieldName = getFieldName(field, wellknown);
|
||||
const fieldValue = getFieldValue(verifiableCredential, field, props);
|
||||
if (
|
||||
(field === 'credentialRegistry' &&
|
||||
CREDENTIAL_REGISTRY_EDIT === 'false') ||
|
||||
!fieldValue
|
||||
)
|
||||
return;
|
||||
return (
|
||||
<Row
|
||||
key={field}
|
||||
style={{flexDirection: 'row', flex: 1}}
|
||||
align="space-between"
|
||||
let
|
||||
margin="0 8 5 8">
|
||||
<VCItemField
|
||||
key={field}
|
||||
fieldName={fieldName}
|
||||
fieldValue={fieldValue}
|
||||
verifiableCredential={verifiableCredential}
|
||||
wellknown={wellknown}
|
||||
/>
|
||||
</Row>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
export const isVCLoaded = (verifiableCredential: any, fields: string[]) => {
|
||||
return verifiableCredential != null && fields.length > 0;
|
||||
};
|
||||
|
||||
export const getIssuerLogo = (isOpenId4VCI: boolean, issuerLogo: logoType) => {
|
||||
if (isOpenId4VCI) {
|
||||
return (
|
||||
<Image
|
||||
src={issuerLogo?.url}
|
||||
alt={issuerLogo?.alt_text}
|
||||
style={Theme.Styles.issuerLogo}
|
||||
resizeMethod="scale"
|
||||
resizeMode="contain"
|
||||
/>
|
||||
);
|
||||
}
|
||||
return SvgImage.MosipLogo(Theme.Styles.logo);
|
||||
};
|
||||
36
components/ui/ActivityIndicator.tsx
Normal file
36
components/ui/ActivityIndicator.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import {Centered, Column} from './Layout';
|
||||
import {View} from 'react-native';
|
||||
import {Theme} from './styleUtils';
|
||||
import testIDProps from '../../shared/commonUtil';
|
||||
import Spinner from 'react-native-spinkit';
|
||||
import React from 'react';
|
||||
import {SvgImage} from './svg';
|
||||
|
||||
export const ActivityIndicator = () => {
|
||||
return (
|
||||
<Centered
|
||||
style={{backgroundColor: Theme.Colors.whiteBackgroundColor}}
|
||||
crossAlign="center"
|
||||
fill>
|
||||
<Column
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignSelf: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
margin="24 0"
|
||||
align="center"
|
||||
crossAlign="center">
|
||||
{SvgImage.ProgressIcon()}
|
||||
<View {...testIDProps('threeDotsLoader')}>
|
||||
<Spinner
|
||||
type="ThreeBounce"
|
||||
color={Theme.Colors.Loading}
|
||||
style={{marginLeft: 6}}
|
||||
/>
|
||||
</View>
|
||||
</Column>
|
||||
</Centered>
|
||||
);
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import {StyleProp, TextStyle, Text as RNText} from 'react-native';
|
||||
import {Theme, Spacing} from './styleUtils';
|
||||
import {StyleProp, Text as RNText, TextStyle} from 'react-native';
|
||||
import {Spacing, Theme} from './styleUtils';
|
||||
import testIDProps from '../../shared/commonUtil';
|
||||
|
||||
export const Text: React.FC<TextProps> = (props: TextProps) => {
|
||||
@@ -21,6 +21,7 @@ export const Text: React.FC<TextProps> = (props: TextProps) => {
|
||||
{...testIDProps(props.testID)}
|
||||
style={textStyles}
|
||||
numberOfLines={props.numLines}
|
||||
ellipsizeMode={props.ellipsizeMode}
|
||||
accessible={props.accessible}>
|
||||
{props.children}
|
||||
</RNText>
|
||||
@@ -37,6 +38,7 @@ interface TextProps {
|
||||
size?: 'small' | 'extraSmall' | 'smaller' | 'regular' | 'large';
|
||||
lineHeight?: number;
|
||||
numLines?: number;
|
||||
ellipsizeMode?: 'head' | 'middle' | 'tail' | 'clip' | undefined;
|
||||
style?: StyleProp<TextStyle>;
|
||||
accessible?: boolean | true;
|
||||
}
|
||||
|
||||
@@ -338,6 +338,7 @@ export const DefaultTheme = {
|
||||
flex: 1,
|
||||
padding: 10,
|
||||
overflow: 'hidden',
|
||||
borderRadius: 10,
|
||||
},
|
||||
successTag: {
|
||||
backgroundColor: Colors.Green,
|
||||
@@ -372,8 +373,8 @@ export const DefaultTheme = {
|
||||
height: 60,
|
||||
},
|
||||
vcDetailsLogo: {
|
||||
height: 35,
|
||||
width: 90,
|
||||
height: 50,
|
||||
width: 50,
|
||||
},
|
||||
homeCloseCardDetailsHeader: {
|
||||
flex: 1,
|
||||
@@ -756,6 +757,7 @@ export const DefaultTheme = {
|
||||
color: 'transparent',
|
||||
backgroundColor: Colors.Grey5,
|
||||
borderRadius: 4,
|
||||
marginBottom: 2,
|
||||
},
|
||||
subtitle: {
|
||||
backgroundColor: 'transparent',
|
||||
|
||||
@@ -342,6 +342,7 @@ export const PurpleTheme = {
|
||||
flex: 1,
|
||||
padding: 10,
|
||||
overflow: 'hidden',
|
||||
borderRadius: 10,
|
||||
},
|
||||
successTag: {
|
||||
backgroundColor: Colors.Green,
|
||||
@@ -376,8 +377,8 @@ export const PurpleTheme = {
|
||||
height: 60,
|
||||
},
|
||||
vcDetailsLogo: {
|
||||
width: 90,
|
||||
height: 35,
|
||||
width: 50,
|
||||
height: 50,
|
||||
},
|
||||
homeCloseCardDetailsHeader: {
|
||||
flex: 1,
|
||||
@@ -759,6 +760,7 @@ export const PurpleTheme = {
|
||||
color: 'transparent',
|
||||
backgroundColor: Colors.Grey5,
|
||||
borderRadius: 4,
|
||||
marginBottom: 2,
|
||||
},
|
||||
subtitle: {
|
||||
backgroundColor: 'transparent',
|
||||
|
||||
@@ -576,7 +576,16 @@ export const IssuersMachine = model.createMachine(
|
||||
},
|
||||
checkInternet: async () => await NetInfo.fetch(),
|
||||
downloadIssuerConfig: async (context, _) => {
|
||||
return await CACHED_API.fetchIssuerConfig(context.selectedIssuerId);
|
||||
let issuersConfig = await CACHED_API.fetchIssuerConfig(
|
||||
context.selectedIssuerId,
|
||||
);
|
||||
if (context.selectedIssuer['.well-known']) {
|
||||
await CACHED_API.fetchIssuerWellknownConfig(
|
||||
context.selectedIssuerId,
|
||||
context.selectedIssuer['.well-known'],
|
||||
);
|
||||
}
|
||||
return issuersConfig;
|
||||
},
|
||||
downloadCredential: async context => {
|
||||
const body = await getBody(context);
|
||||
|
||||
134
package-lock.json
generated
134
package-lock.json
generated
@@ -75,6 +75,7 @@
|
||||
"react-native-screens": "~3.20.0",
|
||||
"react-native-secure-key-store": "^2.0.10",
|
||||
"react-native-securerandom": "^1.0.1",
|
||||
"react-native-shimmer-placeholder": "^2.0.9",
|
||||
"react-native-spinkit": "^1.5.1",
|
||||
"react-native-svg": "13.4.0",
|
||||
"react-native-vector-icons": "^10.0.0",
|
||||
@@ -8664,21 +8665,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/core/node_modules/typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/hast-util-to-babel-ast": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz",
|
||||
@@ -8783,21 +8769,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@svgr/plugin-svgo/node_modules/typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/@trysound/sax": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
|
||||
@@ -12529,29 +12500,6 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/encoding": {
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
||||
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"iconv-lite": "^0.6.2"
|
||||
}
|
||||
},
|
||||
"node_modules/encoding/node_modules/iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/end-of-stream": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
@@ -13856,7 +13804,6 @@
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-1.5.1.tgz",
|
||||
"integrity": "sha512-yt5a1VCp2BF9CrsO689PCD5oXKP14MMhnOanQMvDn4BDpURYfzAlDVGC5fZrNQKtwn/eq3bcrxIwZ7D9QjVVRg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@expo/config": "~8.1.0",
|
||||
"chalk": "^4.1.0",
|
||||
@@ -13873,7 +13820,6 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
@@ -13888,7 +13834,6 @@
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
@@ -13904,7 +13849,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
@@ -13921,7 +13865,6 @@
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
@@ -13930,7 +13873,6 @@
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
@@ -13945,7 +13887,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -13954,7 +13895,6 @@
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
@@ -13966,7 +13906,6 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
@@ -24738,9 +24677,9 @@
|
||||
"integrity": "sha512-c7Cs+YQN26UaQsRG1dmlXL7VL2ctnXwH/dl0IOMEQ7ZaL2NdN313YSAI8ZEZZjrVhNmPsyWEuvTFqWrdpItqQg=="
|
||||
},
|
||||
"node_modules/react-native-linear-gradient": {
|
||||
"version": "2.8.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.2.tgz",
|
||||
"integrity": "sha512-hgmCsgzd58WNcDCyPtKrvxsaoETjb/jLGxis/dmU3Aqm2u4ICIduj4ECjbil7B7pm9OnuTkmpwXu08XV2mpg8g==",
|
||||
"version": "2.8.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz",
|
||||
"integrity": "sha512-KflAXZcEg54PXkLyflaSZQ3PJp4uC4whM7nT/Uot9m0e/qxFV3p6uor1983D1YOBJbJN7rrWdqIjq0T42jOJyA==",
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
@@ -24898,6 +24837,15 @@
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-shimmer-placeholder": {
|
||||
"version": "2.0.9",
|
||||
"resolved": "https://registry.npmjs.org/react-native-shimmer-placeholder/-/react-native-shimmer-placeholder-2.0.9.tgz",
|
||||
"integrity": "sha512-s2pfAAO6uaybREYM2KcaxP3c2XlZvLfHfzmhMlGEoOhSKaoM92KpA1Hx0BeC75yilkliJuowqO/hFzvLB0h7hg==",
|
||||
"peerDependencies": {
|
||||
"prop-types": ">=15.6.0",
|
||||
"react-native-linear-gradient": ">=2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-size-matters": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-size-matters/-/react-native-size-matters-0.3.1.tgz",
|
||||
@@ -35406,14 +35354,6 @@
|
||||
"json-parse-even-better-errors": "^2.3.0",
|
||||
"lines-and-columns": "^1.1.6"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -35473,14 +35413,6 @@
|
||||
"json-parse-even-better-errors": "^2.3.0",
|
||||
"lines-and-columns": "^1.1.6"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -38349,28 +38281,6 @@
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||
},
|
||||
"encoding": {
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
||||
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"iconv-lite": "^0.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
@@ -39390,7 +39300,6 @@
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-1.5.1.tgz",
|
||||
"integrity": "sha512-yt5a1VCp2BF9CrsO689PCD5oXKP14MMhnOanQMvDn4BDpURYfzAlDVGC5fZrNQKtwn/eq3bcrxIwZ7D9QjVVRg==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@expo/config": "~8.1.0",
|
||||
"chalk": "^4.1.0",
|
||||
@@ -39404,7 +39313,6 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
@@ -39413,7 +39321,6 @@
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
@@ -39423,7 +39330,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
@@ -39442,7 +39348,6 @@
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
@@ -39459,7 +39364,6 @@
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
@@ -47566,9 +47470,9 @@
|
||||
"integrity": "sha512-c7Cs+YQN26UaQsRG1dmlXL7VL2ctnXwH/dl0IOMEQ7ZaL2NdN313YSAI8ZEZZjrVhNmPsyWEuvTFqWrdpItqQg=="
|
||||
},
|
||||
"react-native-linear-gradient": {
|
||||
"version": "2.8.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.2.tgz",
|
||||
"integrity": "sha512-hgmCsgzd58WNcDCyPtKrvxsaoETjb/jLGxis/dmU3Aqm2u4ICIduj4ECjbil7B7pm9OnuTkmpwXu08XV2mpg8g==",
|
||||
"version": "2.8.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz",
|
||||
"integrity": "sha512-KflAXZcEg54PXkLyflaSZQ3PJp4uC4whM7nT/Uot9m0e/qxFV3p6uor1983D1YOBJbJN7rrWdqIjq0T42jOJyA==",
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-localize": {
|
||||
@@ -47670,6 +47574,12 @@
|
||||
"base64-js": "*"
|
||||
}
|
||||
},
|
||||
"react-native-shimmer-placeholder": {
|
||||
"version": "2.0.9",
|
||||
"resolved": "https://registry.npmjs.org/react-native-shimmer-placeholder/-/react-native-shimmer-placeholder-2.0.9.tgz",
|
||||
"integrity": "sha512-s2pfAAO6uaybREYM2KcaxP3c2XlZvLfHfzmhMlGEoOhSKaoM92KpA1Hx0BeC75yilkliJuowqO/hFzvLB0h7hg==",
|
||||
"requires": {}
|
||||
},
|
||||
"react-native-size-matters": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-size-matters/-/react-native-size-matters-0.3.1.tgz",
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
"react-native-screens": "~3.20.0",
|
||||
"react-native-secure-key-store": "^2.0.10",
|
||||
"react-native-securerandom": "^1.0.1",
|
||||
"react-native-shimmer-placeholder": "^2.0.9",
|
||||
"react-native-spinkit": "^1.5.1",
|
||||
"react-native-svg": "13.4.0",
|
||||
"react-native-vector-icons": "^10.0.0",
|
||||
|
||||
@@ -15,6 +15,10 @@ export const API_URLS: ApiUrls = {
|
||||
buildURL: (issuerId: string): `/${string}` =>
|
||||
`/residentmobileapp/issuers/${issuerId}`,
|
||||
},
|
||||
issuerWellknownConfig: {
|
||||
method: 'GET',
|
||||
buildURL: (requestUrl: `/${string}`): `/${string}` => requestUrl,
|
||||
},
|
||||
allProperties: {
|
||||
method: 'GET',
|
||||
buildURL: (): `/${string}` => '/residentmobileapp/allProperties',
|
||||
@@ -96,7 +100,13 @@ export const API = {
|
||||
);
|
||||
return response.response;
|
||||
},
|
||||
|
||||
fetchIssuerWellknownConfig: async (requestUrl: string) => {
|
||||
const response = await request(
|
||||
API_URLS.issuerWellknownConfig.method,
|
||||
API_URLS.issuerWellknownConfig.buildURL(requestUrl),
|
||||
);
|
||||
return response;
|
||||
},
|
||||
fetchAllProperties: async () => {
|
||||
const response = await request(
|
||||
API_URLS.allProperties.method,
|
||||
@@ -118,6 +128,11 @@ export const CACHED_API = {
|
||||
cacheKey: API_CACHED_STORAGE_KEYS.fetchIssuerConfig(issuerId),
|
||||
fetchCall: API.fetchIssuerConfig.bind(null, issuerId),
|
||||
}),
|
||||
fetchIssuerWellknownConfig: (issuerId: string, requestUrl: string) =>
|
||||
generateCacheAPIFunction({
|
||||
cacheKey: API_CACHED_STORAGE_KEYS.fetchIssuerWellknownConfig(issuerId),
|
||||
fetchCall: API.fetchIssuerWellknownConfig.bind(null, requestUrl),
|
||||
}),
|
||||
|
||||
getAllProperties: (isCachePreferred: boolean) =>
|
||||
generateCacheAPIFunction({
|
||||
@@ -246,6 +261,7 @@ type Api_Params = {
|
||||
type ApiUrls = {
|
||||
issuersList: Api_Params;
|
||||
issuerConfig: Api_Params;
|
||||
issuerWellknownConfig: Api_Params;
|
||||
allProperties: Api_Params;
|
||||
getIndividualId: Api_Params;
|
||||
reqIndividualOTP: Api_Params;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {Platform} from 'react-native';
|
||||
import {MIMOTO_HOST, ESIGNET_HOST, DEBUG_MODE} from 'react-native-dotenv';
|
||||
import {DEBUG_MODE, ESIGNET_HOST, MIMOTO_HOST} from 'react-native-dotenv';
|
||||
import {Argon2iConfig} from './commonUtil';
|
||||
import {VcIdType} from '../types/VC/ExistingMosipVC/vc';
|
||||
|
||||
@@ -31,9 +31,9 @@ export const APP_ID_LENGTH = 12;
|
||||
// Numbers and Upper case Alphabets without confusing characters like 0, 1, 2, I, O, Z
|
||||
// prettier-ignore
|
||||
export const APP_ID_DICTIONARY = [
|
||||
'3', '4', '5', '6', '7', '8', '9',
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L',
|
||||
'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
|
||||
'3', '4', '5', '6', '7', '8', '9',
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L',
|
||||
'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
|
||||
];
|
||||
|
||||
export function isIOS(): boolean {
|
||||
@@ -74,3 +74,23 @@ export type IndividualId = {
|
||||
export const NETWORK_REQUEST_FAILED = 'Network request failed';
|
||||
export const REQUEST_TIMEOUT = 'request timedout';
|
||||
export const BIOMETRIC_CANCELLED = 'User has cancelled biometric';
|
||||
|
||||
export const CARD_VIEW_DEFAULT_FIELDS = ['fullName'];
|
||||
|
||||
export const DETAIL_VIEW_DEFAULT_FIELDS = [
|
||||
'fullName',
|
||||
'gender',
|
||||
'phone',
|
||||
'dateOfBirth',
|
||||
'email',
|
||||
'address',
|
||||
];
|
||||
|
||||
//todo UIN & VID to be removed once we get the fields in the wellknown endpoint
|
||||
export const CARD_VIEW_ADD_ON_FIELDS = ['idType', 'UIN', 'VID'];
|
||||
export const DETAIL_VIEW_ADD_ON_FIELDS = [
|
||||
'UIN',
|
||||
'VID',
|
||||
'status',
|
||||
'credentialRegistry',
|
||||
];
|
||||
|
||||
@@ -8,6 +8,7 @@ import {CredentialWrapper} from '../../types/VC/EsignetMosipVC/vc';
|
||||
import {VCMetadata} from '../VCMetadata';
|
||||
import i18next from 'i18next';
|
||||
import {getJWT} from '../cryptoutil/cryptoUtil';
|
||||
import {CACHED_API} from '../api';
|
||||
|
||||
export const Protocols = {
|
||||
OpenId4VCI: 'OpenId4VCI',
|
||||
@@ -66,6 +67,10 @@ export const updateCredentialInformation = (context, credential) => {
|
||||
credentialWrapper.verifiableCredential = credential;
|
||||
credentialWrapper.identifier = getIdentifier(context, credential);
|
||||
credentialWrapper.generatedOn = new Date();
|
||||
credentialWrapper.verifiableCredential.wellKnown =
|
||||
context.selectedIssuer['.well-known'];
|
||||
// credentialWrapper.verifiableCredential.wellKnown =
|
||||
// 'https://esignet.collab.mosip.net/.well-known/openid-credential-issuer';
|
||||
credentialWrapper.verifiableCredential.issuerLogo =
|
||||
getDisplayObjectForCurrentLanguage(context.selectedIssuer.display)?.logo;
|
||||
return credentialWrapper;
|
||||
@@ -136,6 +141,28 @@ export const getJWK = async publicKey => {
|
||||
}
|
||||
};
|
||||
|
||||
export const getCredentialIssuersWellKnownConfig = async (
|
||||
issuer: string,
|
||||
wellknown: string,
|
||||
defaultFields: string[],
|
||||
) => {
|
||||
let fields: string[] = defaultFields;
|
||||
let response = null;
|
||||
if (wellknown) {
|
||||
response = await CACHED_API.fetchIssuerWellknownConfig(issuer, wellknown);
|
||||
fields = !response
|
||||
? []
|
||||
: Object.keys(
|
||||
response?.credentials_supported[0].credential_definition
|
||||
.credentialSubject,
|
||||
);
|
||||
}
|
||||
return {
|
||||
wellknown: response,
|
||||
fields: fields,
|
||||
};
|
||||
};
|
||||
|
||||
export const vcDownloadTimeout = async (): Promise<number> => {
|
||||
const response = await getAllConfigurations();
|
||||
|
||||
@@ -150,6 +177,7 @@ export enum OIDCErrors {
|
||||
INVALID_TOKEN_SPECIFIED = 'Invalid token specified',
|
||||
OIDC_CONFIG_ERROR_PREFIX = 'Config error',
|
||||
}
|
||||
|
||||
// ErrorMessage is the type of error message shown in the UI
|
||||
export enum ErrorMessage {
|
||||
NO_INTERNET = 'noInternetConnection',
|
||||
|
||||
@@ -27,20 +27,21 @@ export async function request(
|
||||
if (path.includes('residentmobileapp'))
|
||||
headers['X-AppId'] = __AppId.getValue();
|
||||
let response;
|
||||
const requestUrl = path.indexOf('https://') != -1 ? path : host + path;
|
||||
if (timeoutMillis === undefined) {
|
||||
response = await fetch(host + path, {
|
||||
response = await fetch(requestUrl, {
|
||||
method,
|
||||
headers,
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
});
|
||||
} else {
|
||||
console.log(`making a web request to ${host + path}`);
|
||||
console.log(`making a web request to ${requestUrl}`);
|
||||
let controller = new AbortController();
|
||||
setTimeout(() => {
|
||||
controller.abort();
|
||||
}, timeoutMillis);
|
||||
try {
|
||||
response = await fetch(host + path, {
|
||||
response = await fetch(requestUrl, {
|
||||
method,
|
||||
headers,
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
|
||||
@@ -42,6 +42,8 @@ export const API_CACHED_STORAGE_KEYS = {
|
||||
fetchIssuers: 'CACHE_FETCH_ISSUERS',
|
||||
fetchIssuerConfig: (issuerId: string) =>
|
||||
`CACHE_FETCH_ISSUER_CONFIG_${issuerId}`,
|
||||
fetchIssuerWellknownConfig: (issuerId: string) =>
|
||||
`CACHE_FETCH_ISSUER_WELLKNOWN_CONFIG_${issuerId}`,
|
||||
};
|
||||
|
||||
async function generateHmac(
|
||||
|
||||
@@ -72,6 +72,7 @@ export interface VerifiableCredential {
|
||||
issuerLogo: logoType;
|
||||
format: string;
|
||||
credential: Credential;
|
||||
wellKnown: string;
|
||||
}
|
||||
|
||||
export interface CredentialWrapper {
|
||||
|
||||
Reference in New Issue
Block a user