Skip to content

Commit

Permalink
fix: dcql json claims
Browse files Browse the repository at this point in the history
  • Loading branch information
auer-martin committed Nov 26, 2024
1 parent af89f1a commit e96566d
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 35 deletions.
30 changes: 2 additions & 28 deletions packages/core/src/modules/dcql/DcqlService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { AgentContext } from '../../agent'
import { DcqlCredential, DcqlMdocCredential, DcqlQuery, DcqlSdJwtVcCredential } from 'dcql'
import { injectable } from 'tsyringe'

import { JsonValue } from '../../types'
import { Mdoc, MdocApi, MdocDeviceResponse, MdocOpenId4VpSessionTranscriptOptions, MdocRecord } from '../mdoc'
import { SdJwtVcApi, SdJwtVcRecord, SdJwtVcService } from '../sd-jwt-vc'
import { buildDisclosureFrameForPayload } from '../sd-jwt-vc/disclosureFrame'
Expand All @@ -18,19 +17,6 @@ import {
} from './models'
import { dcqlGetPresentationsToCreate as getDcqlVcPresentationsToCreate } from './utils'

interface HasToJson {
toJson(): JsonValue
}

function isToJsonable(value: unknown): value is HasToJson {
return (
value !== null &&
typeof value === 'object' &&
'toJson' in value &&
typeof (value as HasToJson).toJson === 'function'
)
}

/**
* @todo create a public api for using dif presentation exchange
*/
Expand Down Expand Up @@ -113,23 +99,11 @@ export class DcqlService {

const dcqlCredentials: DcqlCredential[] = credentialRecords.map((record) => {
if (record.type === 'MdocRecord') {
const transformValue = (value: unknown): unknown => {
if (typeof value !== 'function' && typeof value !== 'object') return value
return isToJsonable(value) ? value.toJson() : 'unknown json representation'
}

const mdoc = Mdoc.fromBase64Url(record.base64Url)

const namespaces = Object.fromEntries(
Object.entries(mdoc.issuerSignedNamespaces).map(([key, namespace]) => [
key,
Object.fromEntries(Object.entries(namespace).map(([k, v]) => [k, transformValue(v)])),
])
)
return {
credential_format: 'mso_mdoc',
doctype: record.getTags().docType,
namespaces,
namespaces: mdoc.issuerSignedNamespaces,
} satisfies DcqlMdocCredential
} else if (record.type === 'SdJwtVcRecord') {
return {
Expand All @@ -152,7 +126,7 @@ export class DcqlService {
const sdJwtVcRecord = credentialRecords[result.input_credential_index] as SdJwtVcRecord
const claims = agentContext.dependencyManager
.resolve(SdJwtVcService)
.applyDisclosuresForPayload(sdJwtVcRecord.compactSdJwtVc, result.output.claims)
.applyDisclosuresForPayload(sdJwtVcRecord.compactSdJwtVc, result.output.claims).prettyClaims
return [
credential_query_id,
{
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/modules/mdoc/MdocOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type { Key } from '../../crypto/Key'
import type { DifPresentationExchangeDefinition } from '../dif-presentation-exchange'
import type { ValidityInfo } from '@animo-id/mdoc'

export { DateOnly } from '@animo-id/mdoc'

export type MdocNameSpaces = Record<string, Record<string, unknown>>

export interface MdocVerificationContext {
Expand Down
29 changes: 22 additions & 7 deletions packages/openid4vc/tests/openid4vc.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
JwtPayload,
SdJwtVcRecord,
MdocRecord,
DateOnly,
} from '@credo-ts/core'
import express, { type Express } from 'express'

Expand Down Expand Up @@ -2252,6 +2253,8 @@ describe('OpenId4Vc', () => {

const holderKey = await holder.agent.context.wallet.createKey({ keyType: KeyType.P256 })

const date = new DateOnly()

const signedMdoc = await issuer.agent.mdoc.sign({
docType: 'org.eu.university',
holderKey,
Expand All @@ -2260,6 +2263,7 @@ describe('OpenId4Vc', () => {
'eu.europa.ec.eudi.pid.1': {
university: 'innsbruck',
degree: 'bachelor',
date: date,
name: 'John Doe',
not: 'disclosed',
},
Expand All @@ -2286,6 +2290,7 @@ describe('OpenId4Vc', () => {
claims: [
{ namespace: 'eu.europa.ec.eudi.pid.1', claim_name: 'name' },
{ namespace: 'eu.europa.ec.eudi.pid.1', claim_name: 'degree' },
{ namespace: 'eu.europa.ec.eudi.pid.1', claim_name: 'date' },
],
},
{
Expand Down Expand Up @@ -2322,6 +2327,7 @@ describe('OpenId4Vc', () => {
claims: [
{ namespace: 'eu.europa.ec.eudi.pid.1', claim_name: 'name' },
{ namespace: 'eu.europa.ec.eudi.pid.1', claim_name: 'degree' },
{ namespace: 'eu.europa.ec.eudi.pid.1', claim_name: 'date' },
],
meta: { doctype_value: 'org.eu.university' },
},
Expand All @@ -2342,6 +2348,7 @@ describe('OpenId4Vc', () => {
credential_format: 'mso_mdoc',
namespaces: {
'eu.europa.ec.eudi.pid.1': {
date: expect.any(DateOnly),
name: 'John Doe',
degree: 'bachelor',
},
Expand All @@ -2359,7 +2366,14 @@ describe('OpenId4Vc', () => {
credential_format: 'vc+sd-jwt',
vct: 'OpenBadgeCredential',
claims: {
cnf: {
kid: 'did:key:z6MkpGR4gs4Rc3Zph4vj8wRnjnAxgAPSxcR8MAVKutWspQzc#z6MkpGR4gs4Rc3Zph4vj8wRnjnAxgAPSxcR8MAVKutWspQzc',
},
degree: 'bachelor',
iat: expect.any(Number),
iss: 'did:key:z6MkrzQPBr4pyqC776KKtrz13SchM5ePPbssuPuQZb5t4uKQ',
university: 'innsbruck',
vct: 'OpenBadgeCredential',
},
},
input_credential_index: 1,
Expand Down Expand Up @@ -2409,6 +2423,14 @@ describe('OpenId4Vc', () => {
const presentation = dcql?.presentation['orgeuuniversity'] as MdocDeviceResponse
expect(presentation.documents).toHaveLength(1)

expect(presentation.documents[0].issuerSignedNamespaces).toEqual({
'eu.europa.ec.eudi.pid.1': {
date,
name: 'John Doe',
degree: 'bachelor',
},
})

const sdJwtPresentation = dcql?.presentation['OpenBadgeCredentialDescriptor'] as SdJwtVc
expect(sdJwtPresentation.prettyClaims).toEqual({
vct: 'OpenBadgeCredential',
Expand Down Expand Up @@ -2566,14 +2588,7 @@ describe('OpenId4Vc', () => {
}),
// Name is NOT in here
disclosedPayload: {
cnf: {
kid: 'did:key:z6MkpGR4gs4Rc3Zph4vj8wRnjnAxgAPSxcR8MAVKutWspQzc#z6MkpGR4gs4Rc3Zph4vj8wRnjnAxgAPSxcR8MAVKutWspQzc',
},
degree: 'bachelor',
iat: expect.any(Number),
iss: 'did:key:z6MkrzQPBr4pyqC776KKtrz13SchM5ePPbssuPuQZb5t4uKQ',
university: 'innsbruck',
vct: 'OpenBadgeCredential',
},
},
],
Expand Down

0 comments on commit e96566d

Please sign in to comment.