mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-09 21:48:04 -05:00
[INJIMOB-3367] add support for sd-jwt vc parsing and rendering (#2042)
* [INJIMOB-3367] add support for sd-jwt vc parsing and rendering Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com> * [INJIMOB-3367] add sha384 and sha 512 support for sd jwt parsing Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com> * [INJIMOB-3367] fix bottom sectionview fields rendering for sdjwt Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com> * [INJIMOB-3367] remove logs Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com> * [INJIMOB-3367] add dc+sd-jwt support Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com> --------- Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>
This commit is contained in:
@@ -3,4 +3,6 @@
|
||||
export enum VCFormat {
|
||||
ldp_vc = 'ldp_vc',
|
||||
mso_mdoc = 'mso_mdoc',
|
||||
vc_sd_jwt = 'vc+sd-jwt',
|
||||
dc_sd_jwt = 'dc+sd-jwt',
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import {VCProcessor} from '../../components/VC/common/VCProcessor';
|
||||
import {
|
||||
BOTTOM_SECTION_FIELDS_WITH_DETAILED_ADDRESS_FIELDS,
|
||||
DETAIL_VIEW_ADD_ON_FIELDS,
|
||||
DETAIL_VIEW_BOTTOM_SECTION_FIELDS,
|
||||
getCredentialTypeFromWellKnown,
|
||||
} from '../../components/VC/common/VCUtils';
|
||||
import {displayType} from '../../machines/Issuers/IssuersMachine';
|
||||
@@ -77,6 +78,12 @@ export const updateCredentialInformation = async (
|
||||
context.selectedCredentialType.format,
|
||||
);
|
||||
}
|
||||
if( context.selectedCredentialType.format === VCFormat.vc_sd_jwt || context.selectedCredentialType.format === VCFormat.dc_sd_jwt) {
|
||||
processedCredential = await VCProcessor.processForRendering(
|
||||
credential,
|
||||
context.selectedCredentialType.format,
|
||||
)
|
||||
}
|
||||
let verifiableCredential;
|
||||
try {
|
||||
verifiableCredential = {
|
||||
@@ -168,7 +175,16 @@ export const getCredentialIssuersWellKnownConfig = async (
|
||||
fields = ldpFields;
|
||||
wellknownFieldsFlag = true;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else if( format === VCFormat.vc_sd_jwt || format === VCFormat.dc_sd_jwt) {
|
||||
const sdJwtFields = flattenClaimPaths(matchingWellknownDetails.claims);
|
||||
|
||||
if (sdJwtFields.length > 0) {
|
||||
fields = sdJwtFields;
|
||||
wellknownFieldsFlag = true
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.error(`Unsupported credential format - ${format} found`);
|
||||
throw new UnsupportedVcFormat(format);
|
||||
}
|
||||
@@ -193,6 +209,28 @@ export const getCredentialIssuersWellKnownConfig = async (
|
||||
wellknownFieldsFlag || matchingWellknownDetails?.order?.length > 0,
|
||||
};
|
||||
};
|
||||
const flattenClaimPaths = (
|
||||
claims: Record<string, any>,
|
||||
prefix = '',
|
||||
): string[] => {
|
||||
return Object.entries(claims).flatMap(([key, value]) => {
|
||||
const currentPath = prefix ? `${prefix}.${key}` : key;
|
||||
|
||||
if (
|
||||
value &&
|
||||
typeof value === 'object' &&
|
||||
!Array.isArray(value) &&
|
||||
Object.keys(value).some(k => typeof value[k] === 'object')
|
||||
) {
|
||||
// Has nested objects inside, so recurse
|
||||
return flattenClaimPaths(value, currentPath);
|
||||
} else {
|
||||
// Either a primitive or an empty object or a leaf with no metadata
|
||||
return [currentPath];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
export const getDetailedViewFields = async (
|
||||
issuer: string,
|
||||
@@ -211,8 +249,7 @@ export const getDetailedViewFields = async (
|
||||
|
||||
let updatedFieldsList = response.fields.concat(DETAIL_VIEW_ADD_ON_FIELDS);
|
||||
|
||||
updatedFieldsList = removeBottomSectionFields(updatedFieldsList);
|
||||
|
||||
updatedFieldsList = removeBottomSectionFields(updatedFieldsList,format);
|
||||
return {
|
||||
matchingCredentialIssuerMetadata: response.matchingCredentialIssuerMetadata,
|
||||
fields: updatedFieldsList,
|
||||
@@ -221,7 +258,13 @@ export const getDetailedViewFields = async (
|
||||
};
|
||||
};
|
||||
|
||||
export const removeBottomSectionFields = fields => {
|
||||
export const removeBottomSectionFields = (fields, format) => {
|
||||
if (format === VCFormat.vc_sd_jwt || format === VCFormat.dc_sd_jwt) {
|
||||
return fields.filter(
|
||||
fieldName => !DETAIL_VIEW_BOTTOM_SECTION_FIELDS.includes(fieldName),
|
||||
);
|
||||
}
|
||||
|
||||
return fields.filter(
|
||||
fieldName =>
|
||||
!BOTTOM_SECTION_FIELDS_WITH_DETAILED_ADDRESS_FIELDS.includes(fieldName) &&
|
||||
|
||||
@@ -61,7 +61,6 @@ async function verifyCredentialForAndroid(
|
||||
typeof verifiableCredential === 'string'
|
||||
? verifiableCredential
|
||||
: JSON.stringify(verifiableCredential);
|
||||
|
||||
const vcVerifierResult = await vcVerifier.verifyCredentials(
|
||||
credentialString,
|
||||
credentialFormat,
|
||||
@@ -73,7 +72,7 @@ async function verifyCredentialForIos(
|
||||
verifiableCredential: Credential,
|
||||
credentialFormat: string,
|
||||
): Promise<VerificationResult> {
|
||||
if (credentialFormat === VCFormat.mso_mdoc) {
|
||||
if (credentialFormat === VCFormat.mso_mdoc || credentialFormat === VCFormat.vc_sd_jwt || credentialFormat === VCFormat.dc_sd_jwt) {
|
||||
return createSuccessfulVerificationResult();
|
||||
}
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user