From d7acf0ce816e239f64868d908d7418102fe1f917 Mon Sep 17 00:00:00 2001 From: RinkalBhojani Date: Fri, 6 Mar 2026 11:14:24 +0530 Subject: [PATCH 1/2] fix:fixed cbor date format issue in Mdoc validityInfo Signed-off-by: RinkalBhojani --- src/utils/oid4vc-agent.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/utils/oid4vc-agent.ts b/src/utils/oid4vc-agent.ts index d254a96e..2981c38e 100644 --- a/src/utils/oid4vc-agent.ts +++ b/src/utils/oid4vc-agent.ts @@ -103,6 +103,7 @@ export function getMixedCredentialRequestToCredentialMapper(): OpenId4VciCredent const parsedCertificate = X509Service.parseCertificate(agentContext, { encodedCertificate: issuerx509certificate[0], }) + console.log(`\n credential validityInfo for mdoc: ${JSON.stringify(credential.payload.validityInfo)} \n`) parsedCertificate.publicJwk.keyId = credential.signerOptions.keyId return { type: 'credentials', @@ -111,6 +112,11 @@ export function getMixedCredentialRequestToCredentialMapper(): OpenId4VciCredent issuerCertificate: parsedCertificate, holderKey: holderBindingDetails.jwk, ...credential.payload, + validityInfo: { + ...credential.payload.validityInfo, + validFrom: new Date(credential.payload.validityInfo.validFrom), + validUntil: new Date(credential.payload.validityInfo.validUntil), + }, docType: credentialConfiguration.doctype, })), } satisfies OpenId4VciSignMdocCredentials @@ -171,7 +177,7 @@ export async function getTrustedCerts() { } const data = await response.json() return data as string[] - } catch (error) { + } catch (error) { // eslint-disable-next-line no-console console.error('Error fetching data:', error) return [] From b4e6dccc1c5fb94329ddf275420b0e6a8aed2191 Mon Sep 17 00:00:00 2001 From: RinkalBhojani Date: Fri, 20 Mar 2026 15:29:33 +0530 Subject: [PATCH 2/2] fix: fixed issue with portrait attribute data type for photoid credential Signed-off-by: RinkalBhojani --- src/utils/helpers.ts | 47 +++++++++++++++++++++++++++++++++++++++ src/utils/oid4vc-agent.ts | 3 +++ 2 files changed, 50 insertions(+) diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 47218a85..28a6a7c4 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -92,3 +92,50 @@ export function getTypeFromCurve(key: Curve | KeyAlgorithm): OkpType | EcType { } return keyTypeInfo } + +type Namespaces = Record + +export function processIsoImages(namespaces: Namespaces): Namespaces { + const IMAGE_FIELDS = ['portrait', 'enrolment_portrait_image'] + + for (const [nsKey, nsValue] of Object.entries(namespaces)) { + if (!nsKey.includes('org.iso')) continue + + for (const field of IMAGE_FIELDS) { + const value = nsValue[field] + + if (value && typeof value === 'string') { + nsValue[field] = safeBase64DataUrlToUint8Array(value) + } + } + } + + return namespaces +} + +function safeBase64DataUrlToUint8Array(dataUrl: string): Uint8Array | string { + try { + if (typeof dataUrl !== 'string') return dataUrl + + // Must contain base64 data + if (!dataUrl.includes('base64,')) return dataUrl + + const parts = dataUrl.split(',') + if (parts.length < 2) return dataUrl + + const base64 = parts[1] + + // Node.js safe decode (will throw if invalid) + const buffer = Buffer.from(base64, 'base64') + + // Extra validation: ensure it decoded something meaningful + if (!buffer || buffer.length === 0) { + return dataUrl + } + + return new Uint8Array(buffer) + } catch (err) { + // fallback → keep original string + return dataUrl + } +} diff --git a/src/utils/oid4vc-agent.ts b/src/utils/oid4vc-agent.ts index 2981c38e..5e831019 100644 --- a/src/utils/oid4vc-agent.ts +++ b/src/utils/oid4vc-agent.ts @@ -10,6 +10,7 @@ import { ClaimFormat, X509ModuleConfig } from '@credo-ts/core' import { OpenId4VciCredentialFormatProfile } from '@credo-ts/openid4vc' import { SignerMethod } from '../enums/enum' +import { processIsoImages } from './helpers' export function getMixedCredentialRequestToCredentialMapper(): OpenId4VciCredentialRequestToCredentialMapper { return async ({ @@ -105,6 +106,8 @@ export function getMixedCredentialRequestToCredentialMapper(): OpenId4VciCredent }) console.log(`\n credential validityInfo for mdoc: ${JSON.stringify(credential.payload.validityInfo)} \n`) parsedCertificate.publicJwk.keyId = credential.signerOptions.keyId + const updatedNamespaces = processIsoImages(credential.payload.namespaces) + credential.payload.namespaces = updatedNamespaces return { type: 'credentials', format: ClaimFormat.MsoMdoc,