[INJIMOB-2452] : Well known discovery with attribute name change (#1744)

* [INJIMOB-2452]: Well known discovery from wallet side with credential_issuer attribute name change.

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

* [INJIMOB-2452]: Add issuer_id for cache key for wellknown call.

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

* [INJIMOB-2452]: Removing fetchIssuerConfig method

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

* [INJIMOB-2452]: Add issuerHost in VcMetadata.

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

* [INJIMOB-2452]: Update params to pass only issuerHost of vcMetadata

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

* [INJIMOb-2452]: Update credential_issuer attribute to credential_issuer_host

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

* [INJIMOB-2452]: add temporary fix for react-native-zip-archive error on github action

Signed-off-by: Alka Prasad <prasadalka1998@gmail.com>

---------

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>
Signed-off-by: Alka Prasad <prasadalka1998@gmail.com>
Co-authored-by: Alka Prasad <prasadalka1998@gmail.com>
This commit is contained in:
balachandarg-tw
2024-12-19 18:59:30 +05:30
committed by GitHub
parent bcad36994d
commit 8fc26b963e
14 changed files with 3845 additions and 47 deletions

View File

@@ -34,7 +34,7 @@ fileignoreconfig:
- filename: shared/fileStorage.ts
checksum: 2ba2721d9722cd9420ae26762316230f7dab1a0be45820cbda4d0ecae0edf957
- filename: screens/Issuers/IssuersScreen.tsx
checksum: 9c53e3770dbefe26e0de67ee4b7d5cc9c52d9823cbb136a1a5104dcb0a101071
checksum: a323497d3276f0ef20ddd6b94d2238a895651d853c3d8f055acc3351dc72da0b
- filename: screens/Home/MyVcs/GetIdInputModal.tsx
checksum: 5c736ed79a372d0ffa7c02eb33d0dc06edbbb08d120978ff287f5f06cd6c7746
- filename: shared/openId4VCI/Utils.ts
@@ -84,7 +84,7 @@ fileignoreconfig:
- filename: screens/Settings/BackupViaPassword.tsx
checksum: d2a355356bcaf8f7ef3b53ba93710cec15fefd0fdf31efd779eebd2bfab61c19
- filename: shared/api.ts
checksum: 05165e469008816a441126f8eed69d54c137d39c3c66e695f8710e8d33a9b038
checksum: 9d5b66705a15f0c2a24f003338d8ac4399de8f389e3ead01dd8f465722381d4b
- filename: machines/backupWithEncryption.ts
checksum: 038c12d30b2312fcbd9230a1c6ddb494d2e561fe0d09741335fa80ab67e2c550
- filename: machines/backupWithEncryption.typegen.ts

View File

@@ -62,6 +62,7 @@ export const VCCardView: React.FC<VCItemProps> = props => {
CARD_VIEW_DEFAULT_FIELDS,
credentialConfigurationId,
format,
props.vcMetadata.issuerHost,
)
.then(response => {
setWellknown(response.matchingCredentialIssuerMetadata);

View File

@@ -239,7 +239,7 @@ export const IssuersActions = (model: any) => {
setSelectedIssuers: model.assign({
selectedIssuer: (context: any, event: any) =>
context.issuers.find(issuer => issuer.credential_issuer === event.id),
context.issuers.find(issuer => issuer.issuer_id === event.id),
}),
updateIssuerFromWellknown: model.assign({

View File

@@ -521,6 +521,7 @@ export interface displayType {
}
export interface issuerType {
issuer_id: string;
credential_issuer: string;
protocol: string;
client_id: string;
@@ -534,4 +535,5 @@ export interface issuerType {
display: [displayType];
credentialTypes: [CredentialTypes];
authorizationEndpoint: string;
credential_issuer_host: string;
}

View File

@@ -41,7 +41,8 @@ export const IssuersService = () => {
checkInternet: async () => await NetInfo.fetch(),
downloadIssuerWellknown: async (context: any) => {
const wellknownResponse = await CACHED_API.fetchIssuerWellknownConfig(
context.selectedIssuerId,
context.selectedIssuer.issuer_id,
context.selectedIssuer.credential_issuer_host,
);
return wellknownResponse;
},
@@ -56,7 +57,7 @@ export const IssuersService = () => {
}
if (credentialTypes.length == 0)
throw new Error(
`No credential type found for issuer ${context.selectedIssuer.credential_issuer}`,
`No credential type found for issuer ${context.selectedIssuer.issuer_id}`,
);
return credentialTypes;
@@ -113,7 +114,7 @@ export const IssuersService = () => {
sendImpressionEvent(
getImpressionEventData(
TelemetryConstants.FlowType.vcDownload,
context.selectedIssuer.credential_issuer +
context.selectedIssuer.issuer_id +
TelemetryConstants.Screens.webViewPage,
),
);

View File

@@ -116,6 +116,7 @@ export const VCItemServices = model => {
fetchIssuerWellknown: async context => {
const wellknownResponse = await CACHED_API.fetchIssuerWellknownConfig(
context.vcMetadata.issuer,
context.vcMetadata.issuerHost,
true,
);
try {

File diff suppressed because it is too large Load Diff

View File

@@ -79,6 +79,7 @@ export const ViewVcModal: React.FC<ViewVcModalProps> = props => {
verifiableCredentialData.credentialConfigurationId,
DETAIL_VIEW_DEFAULT_FIELDS,
verifiableCredentialData.vcMetadata.format,
verifiableCredentialData.vcMetadata.issuerHost,
).then(response => {
setWellknown(response.matchingCredentialIssuerMetadata);
setFields(response.fields);

View File

@@ -285,19 +285,19 @@ export const IssuersScreen: React.FC<
data={filteredSearchData}
renderItem={({item}) => (
<Issuer
testID={removeWhiteSpace(item.credential_issuer)}
key={item.credential_issuer}
testID={removeWhiteSpace(item.issuer_id)}
key={item.issuer_id}
displayDetails={getDisplayObjectForCurrentLanguage(
item.display,
)}
onPress={() =>
onPressHandler(item.credential_issuer, item.protocol)
onPressHandler(item.issuer_id, item.protocol)
}
{...props}
/>
)}
numColumns={1}
keyExtractor={item => item.credential_issuer}
keyExtractor={item => item.issuer_id}
/>
)}
</Column>

View File

@@ -11,7 +11,7 @@ import {SharingStatusModal} from '../Scan/SharingStatusModal';
import {SvgImage} from '../../components/ui/svg';
import {DETAIL_VIEW_DEFAULT_FIELDS} from '../../components/VC/common/VCUtils';
import {getDetailedViewFields} from '../../shared/openId4VCI/Utils';
import { VCProcessor } from '../../components/VC/common/VCProcessor';
import {VCProcessor} from '../../components/VC/common/VCProcessor';
export const ReceiveVcScreen: React.FC = () => {
const {t} = useTranslation('ReceiveVcScreen');
@@ -46,6 +46,7 @@ export const ReceiveVcScreen: React.FC = () => {
verifiableCredentialData.credentialConfigurationId,
DETAIL_VIEW_DEFAULT_FIELDS,
verifiableCredentialData.vcMetadata.format,
verifiableCredentialData.vcMetadata.issuerHost,
).then(response => {
setWellknown(response.matchingCredentialIssuerMetadata);
setFields(response.fields);

View File

@@ -9,7 +9,7 @@ import {Protocols} from './openId4VCI/Utils';
import {getMosipIdentifier} from './commonUtil';
import {VCFormat} from './VCFormat';
import {isMosipVC} from './Utils';
import { getCredentialType } from '../components/VC/common/VCUtils';
import {getCredentialType} from '../components/VC/common/VCUtils';
const VC_KEY_PREFIX = 'VC';
const VC_ITEM_STORE_KEY_REGEX = '^VC_[a-zA-Z0-9_-]+$';
@@ -30,6 +30,8 @@ export class VCMetadata {
downloadKeyType: string = '';
credentialType: string = '';
issuerHost: string = '';
constructor({
idType = '',
requestId = '',
@@ -44,6 +46,7 @@ export class VCMetadata {
downloadKeyType = '',
isExpired = false,
credentialType = '',
issuerHost = '',
} = {}) {
this.idType = idType;
this.requestId = requestId;
@@ -57,7 +60,8 @@ export class VCMetadata {
this.format = format;
this.downloadKeyType = downloadKeyType;
this.isExpired = isExpired;
this.credentialType = credentialType
this.credentialType = credentialType;
this.issuerHost = issuerHost;
}
//TODO: Remove any typing and use appropriate typing
@@ -79,7 +83,8 @@ export class VCMetadata {
? vc.vcMetadata.mosipIndividualId
: getMosipIndividualId(vc.verifiableCredential, vc.issuer),
downloadKeyType: vc.downloadKeyType,
credentialType: vc.credentialType
credentialType: vc.credentialType,
issuerHost: vc.issuerHost,
});
}
@@ -119,7 +124,11 @@ export function parseMetadatas(metadataStrings: object[]) {
return metadataStrings.map(o => new VCMetadata(o));
}
export const getVCMetadata = (context: object, keyType: string, credType: CredentialTypes) => {
export const getVCMetadata = (
context: object,
keyType: string,
credType: CredentialTypes,
) => {
const [issuer, protocol, credentialId] =
context.credentialWrapper?.identifier.split(':');
@@ -133,17 +142,18 @@ export const getVCMetadata = (context: object, keyType: string, credType: Creden
isExpired: context.vcMetadata.isExpired ?? false,
mosipIndividualId: getMosipIndividualId(
context['verifiableCredential'] as VerifiableCredential,
issuer
issuer,
),
format: context['credentialWrapper'].format,
downloadKeyType: keyType,
credentialType: getCredentialType(context.selectedCredentialType)
credentialType: getCredentialType(context.selectedCredentialType),
issuerHost: context.selectedIssuer.credential_issuer_host,
});
};
const getMosipIndividualId = (
verifiableCredential: VerifiableCredential | Credential,
issuer: string
issuer: string,
) => {
try {
const credential = verifiableCredential?.credential

View File

@@ -33,8 +33,8 @@ export const API_URLS: ApiUrls = {
},
issuerWellknownConfig: {
method: 'GET',
buildURL: (issuerId: string): `/${string}` =>
`/v1/mimoto/issuers/${issuerId}/well-known-proxy`,
buildURL: (credentialIssuer: string): string =>
`${credentialIssuer}/.well-known/openid-credential-issuer`,
},
authorizationServerMetadataConfig: {
method: 'GET',
@@ -115,25 +115,19 @@ export const API = {
);
return response.response.issuers || [];
},
fetchIssuerConfig: async (issuerId: string) => {
const response = await request(
API_URLS.issuerConfig.method,
API_URLS.issuerConfig.buildURL(issuerId),
);
return response.response;
},
fetchIssuerWellknownConfig: async (issuerId: string) => {
fetchIssuerWellknownConfig: async (credentialIssuer: string) => {
const response = await request(
API_URLS.issuerWellknownConfig.method,
API_URLS.issuerWellknownConfig.buildURL(issuerId),
API_URLS.issuerWellknownConfig.buildURL(credentialIssuer),
);
return response;
},
fetchAuthorizationServerMetadata: async (authorizationServerUrl: string) => {
const response = await request(
API_URLS.authorizationServerMetadataConfig.method,
API_URLS.authorizationServerMetadataConfig.buildURL(authorizationServerUrl),
API_URLS.authorizationServerMetadataConfig.buildURL(
authorizationServerUrl,
),
undefined,
'',
);
@@ -169,19 +163,15 @@ export const CACHED_API = {
fetchCall: API.fetchIssuers,
}),
fetchIssuerConfig: (issuerId: string) =>
generateCacheAPIFunction({
cacheKey: API_CACHED_STORAGE_KEYS.fetchIssuerConfig(issuerId),
fetchCall: API.fetchIssuerConfig.bind(null, issuerId),
}),
fetchIssuerWellknownConfig: (
issuerId: string,
credentialIssuer: string,
isCachePreferred: boolean = false,
) =>
generateCacheAPIFunction({
isCachePreferred,
cacheKey: API_CACHED_STORAGE_KEYS.fetchIssuerWellknownConfig(issuerId),
fetchCall: API.fetchIssuerWellknownConfig.bind(null, issuerId),
fetchCall: API.fetchIssuerWellknownConfig.bind(null, credentialIssuer),
}),
fetchIssuerAuthorizationServerMetadata: (
@@ -286,10 +276,10 @@ async function generateCacheAPIFunctionWithAPIPreference(
onErrorHardCodedValue != undefined
}`);
console.error(`The error in fetching api ${cacheKey}`,error);
var response=null;
if(!(await NetInfo.fetch()).isConnected){
response = await getItem(cacheKey, null, '');
console.error(`The error in fetching api ${cacheKey}`, error);
var response = null;
if (!(await NetInfo.fetch()).isConnected) {
response = await getItem(cacheKey, null, '');
}
if (response) {
return response;

View File

@@ -65,8 +65,6 @@ export const APP_ID_DICTIONARY = [
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}`,
fetchIssuerAuthorizationServerMetadata: (authorizationServerUrl: string) =>

View File

@@ -79,7 +79,7 @@ export const getIdentifier = (
? credentialIdentifier.split(':')
: credentialIdentifier.split('/');
return (
context.selectedIssuer.credential_issuer +
context.selectedIssuer.issuer_id +
':' +
context.selectedIssuer.protocol +
':' +
@@ -144,7 +144,7 @@ export const constructAuthorizationConfiguration = (
supportedScope: string,
) => {
return {
issuer: selectedIssuer.credential_issuer,
issuer: selectedIssuer.issuer_id,
clientId: selectedIssuer.client_id,
scopes: [supportedScope],
redirectUrl: selectedIssuer.redirect_uri,
@@ -161,11 +161,13 @@ export const getCredentialIssuersWellKnownConfig = async (
defaultFields: string[],
credentialConfigurationId: string,
format: string,
issuerHost: string,
) => {
let fields: string[] = defaultFields;
let matchingWellknownDetails: any;
const wellknownResponse = await CACHED_API.fetchIssuerWellknownConfig(
issuer!,
issuerHost,
);
try {
if (wellknownResponse) {
@@ -220,12 +222,14 @@ export const getDetailedViewFields = async (
credentialConfigurationId: string,
defaultFields: string[],
format: string,
issuerHost: string,
) => {
let response = await getCredentialIssuersWellKnownConfig(
issuer,
defaultFields,
credentialConfigurationId,
format,
issuerHost,
);
let updatedFieldsList = response.fields.concat(DETAIL_VIEW_ADD_ON_FIELDS);
@@ -255,8 +259,8 @@ export const vcDownloadTimeout = async (): Promise<number> => {
// OIDCErrors is a collection of external errors from the OpenID library or the issuer
export const OIDCErrors = {
OIDC_FLOW_CANCELLED_ANDROID : 'User cancelled flow',
OIDC_FLOW_CANCELLED_IOS : 'org.openid.appauth.general error -3',
OIDC_FLOW_CANCELLED_ANDROID: 'User cancelled flow',
OIDC_FLOW_CANCELLED_IOS: 'org.openid.appauth.general error -3',
INVALID_TOKEN_SPECIFIED: 'Invalid token specified',
OIDC_CONFIG_ERROR_PREFIX: 'Config error',