Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/VDX-341 #297

Open
wants to merge 21 commits into
base: feature/SPRIND-137
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7504a67
chore: support dcql in pd-manager and fixed version auto-increment
sanderPostma Dec 17, 2024
b7dc203
chore: OID4VC version up
sanderPostma Dec 17, 2024
4b0c592
Merge remote-tracking branch 'origin/develop' into feature/VDX-341
sanderPostma Dec 17, 2024
ccbd912
chore: lockfile
sanderPostma Dec 17, 2024
ebda0c0
chore: Added withDcqlQuery to RP builder
sanderPostma Dec 17, 2024
fbdad8f
chore: fix for jsonld support
sanderPostma Dec 19, 2024
8880f69
chore: fix for jsonld support
sanderPostma Dec 19, 2024
dfd106f
Merge remote-tracking branch 'origin/feature/SPRIND-137' into feature…
sanderPostma Dec 20, 2024
36c0635
chore: lockfile
sanderPostma Dec 20, 2024
a58764c
Merge remote-tracking branch 'origin/develop' into feature/VDX-341
sanderPostma Jan 7, 2025
877c381
Merge remote-tracking branch 'origin/feature/SPRIND-137' into feature…
sanderPostma Jan 7, 2025
1cfce94
chore: lockfile
sanderPostma Jan 7, 2025
306c946
chore: lib updates
sanderPostma Jan 7, 2025
06944fa
chore: fixed unwrapping json-string as vp_token
sanderPostma Jan 8, 2025
fbdce51
chore: fixed unwrapping vp_token object type
sanderPostma Jan 8, 2025
9a6ccb7
chore: cleanup
sanderPostma Jan 8, 2025
aa4cb0a
chore: removed new error in toWrappedVerifiablePresentation
sanderPostma Jan 8, 2025
32bece4
chore: extra comment
sanderPostma Jan 9, 2025
df3cbbd
chore: use AssertionProofPurpose when there is a domain but not a cha…
sanderPostma Jan 9, 2025
2becfb4
chore: Select AssertionProofPurpose when only challenge is missing
sanderPostma Jan 9, 2025
1a6b469
chore: removed TODO
sanderPostma Jan 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions packages/data-store/src/__tests__/pd-manager.entities.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,83 @@ describe('PresentationDefinitionItemEntity tests', (): void => {
await dbConnection.destroy()
})

it('should create and retrieve PresentationDefinitionItemEntity with dcqlPayload', async (): Promise<void> => {
const repository = dbConnection.getRepository(PresentationDefinitionItemEntity)
const entity = new PresentationDefinitionItemEntity()
entity.definitionId = 'definition1'
entity.version = '1.0'
entity.definitionPayload = JSON.stringify({ id: 'definition1', input_descriptors: [] })
entity.dcqlPayload = JSON.stringify({
credentials: [
{
id: 'credential1',
format: 'jwt_vc',
claims: [
{
namespace: 'test',
claim_name: 'testClaim',
},
],
},
],
})

const savedEntity = await repository.save(entity)
expect(savedEntity).toBeDefined()
expect(savedEntity.id).toBeDefined()
expect(savedEntity.dcqlPayload).toBeDefined()

const retrievedEntity = await repository.findOneBy({ id: savedEntity.id })
expect(retrievedEntity).toBeDefined()
expect(retrievedEntity!.dcqlPayload).toBeDefined()
const parsedDcql = JSON.parse(retrievedEntity!.dcqlPayload)
expect(parsedDcql.credentials[0].id).toEqual('credential1')
})

it('should update PresentationDefinitionItemEntity dcqlPayload', async (): Promise<void> => {
const repository = dbConnection.getRepository(PresentationDefinitionItemEntity)
const entity = new PresentationDefinitionItemEntity()
entity.definitionId = 'definition1'
entity.version = '1.0'
entity.definitionPayload = JSON.stringify({ id: 'definition1', input_descriptors: [] })
entity.dcqlPayload = JSON.stringify({
credentials: [
{
id: 'credential1',
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any kinda of validation on this ID? for example can it be duplicated or null?

Copy link
Contributor Author

@sanderPostma sanderPostma Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The object in question is a query, the field can be anything or be omitted just like could be done with SQL queries

format: 'jwt_vc',
claims: [
{
namespace: 'test',
claim_name: 'testClaim',
},
],
},
],
})

const savedEntity = await repository.save(entity)
expect(savedEntity).toBeDefined()

const updatedDcql = {
credentials: [
{
id: 'credential2',
format: 'jwt_vc',
claims: [
{
namespace: 'test',
claim_name: 'updatedClaim',
},
],
},
],
}
savedEntity.dcqlPayload = JSON.stringify(updatedDcql)
const updatedEntity = await repository.save(savedEntity)
expect(updatedEntity).toBeDefined()
expect(JSON.parse(updatedEntity.dcqlPayload).credentials[0].id).toEqual('credential2')
})

it('should create and retrieve PresentationDefinitionItemEntity', async (): Promise<void> => {
const repository = dbConnection.getRepository(PresentationDefinitionItemEntity)
const entity = new PresentationDefinitionItemEntity()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ export class PresentationDefinitionItemEntity extends BaseEntity {
@Column({ name: 'name', length: 255, type: 'varchar', nullable: true, unique: false })
name?: string

@Column({ name: 'definition_payload', type: 'text', nullable: false, unique: false })
@IsNotEmpty({ message: 'A blank definition payload field is not allowed' })
@Column({ name: 'definition_payload', type: 'text', nullable: false, unique: false }) // TODO should this become nullable now we have dcqlPayload?
@IsNotEmpty({ message: 'A blank PD definition payload field is not allowed' })
definitionPayload!: string

@Column({ name: 'dcql_payload', type: 'text', nullable: true, unique: false })
@IsNotEmpty({ message: 'A blank dcql definition payload field is not allowed' })
dcqlPayload!: string

@CreateDateColumn({ name: 'created_at', nullable: false, type: typeOrmDateTime() })
createdAt!: Date

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ CREATE TABLE "PresentationDefinitionItem" (
"version" TEXT NOT NULL,
"purpose" TEXT,
"definition_payload" TEXT NOT NULL,
"dcql_payload" TEXT,
"created_at" TIMESTAMP NOT NULL DEFAULT now(),
"last_updated_at" TIMESTAMP NOT NULL DEFAULT now(),
CONSTRAINT "PK_PresentationDefinitionItem_id" PRIMARY KEY ("id"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class CreatePresentationDefinitions1716475165344 implements MigrationInte
"version" varchar NOT NULL,
"purpose" varchar,
"definition_payload" varchar NOT NULL,
"dcql_payload" varchar,
"created_at" datetime NOT NULL DEFAULT (datetime('now')),
"last_updated_at" datetime NOT NULL DEFAULT (datetime('now')))`,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IPresentationDefinition } from '@sphereon/pex'
import { DcqlQuery } from '@sphereon/ssi-types'

export type PresentationDefinitionItem = {
id: string
Expand All @@ -8,10 +9,11 @@ export type PresentationDefinitionItem = {
name?: string
purpose?: string
definitionPayload: IPresentationDefinition
dcqlPayload?: DcqlQuery
createdAt: Date
lastUpdatedAt: Date
}

export type NonPersistedPresentationDefinitionItem = Omit<PresentationDefinitionItem, 'id' | 'createdAt' | 'lastUpdatedAt'>
export type PartialPresentationDefinitionItem = Partial<PresentationDefinitionItem>
export type PresentationDefinitionItemFilter = Partial<Omit<PresentationDefinitionItem, 'definitionPayload'>> // TODO add logic to linearize & hash definitionPayload into a separate column so we can filter on it?
export type PresentationDefinitionItemFilter = Partial<Omit<PresentationDefinitionItem, 'definitionPayload' | 'dcqlPayload'>> // TODO add logic to linearize & hash definitionPayload into a separate column so we can filter on it?
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this todo to a ticket and link it on the comment? it can easily be lost on the code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I changed my mind and removed the TODO. The same presentation definition payload can be used for multiple configurations and retrieving records by payload hash may not return the intended record or multiple records, so better to avoid it. The caller just needs to the either the unique ID or definitionId + tenantId + version to query the correct record.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { IPresentationDefinition } from '@sphereon/pex'
import { NonPersistedPresentationDefinitionItem, PartialPresentationDefinitionItem, PresentationDefinitionItem } from '../../types'
import { blake2bHex } from 'blakejs'
import { replaceNullWithUndefined } from '../FormattingUtils'
import { DcqlQuery } from '@sphereon/ssi-types/dist/types/dcql'

export const presentationDefinitionItemFrom = (entity: PresentationDefinitionItemEntity): PresentationDefinitionItem => {
const result: PresentationDefinitionItem = {
Expand All @@ -13,6 +14,7 @@ export const presentationDefinitionItemFrom = (entity: PresentationDefinitionIte
name: entity.name,
purpose: entity.purpose,
definitionPayload: JSON.parse(entity.definitionPayload) as IPresentationDefinition,
dcqlPayload: JSON.parse(entity.dcqlPayload) as DcqlQuery,
createdAt: entity.createdAt,
lastUpdatedAt: entity.lastUpdatedAt,
}
Expand All @@ -29,6 +31,7 @@ export const presentationDefinitionEntityItemFrom = (item: NonPersistedPresentat
entity.name = item.name
entity.purpose = item.purpose
entity.definitionPayload = JSON.stringify(item.definitionPayload!)
entity.dcqlPayload = JSON.stringify(item.dcqlPayload!)
return entity
}

Expand Down
8 changes: 4 additions & 4 deletions packages/ebsi-support/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
},
"dependencies": {
"@ethersproject/random": "^5.7.0",
"@sphereon/did-auth-siop": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/did-auth-siop-adapter": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/did-auth-siop": "0.16.1-feature.SPRIND.137.254",
"@sphereon/did-auth-siop-adapter": "0.16.1-feature.SPRIND.137.254",
"@sphereon/pex": "5.0.0-unstable.28",
"@sphereon/pex-models": "^2.3.2",
"@sphereon/ssi-sdk-ext.did-resolver-ebsi": "0.27.0",
Expand Down Expand Up @@ -44,8 +44,8 @@
"xstate": "^4.38.3"
},
"devDependencies": {
"@sphereon/oid4vci-client": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vci-client": "0.16.1-feature.SPRIND.137.254",
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254",
"@sphereon/ssi-express-support": "workspace:*",
"@sphereon/ssi-sdk-ext.key-manager": "0.27.0",
"@sphereon/ssi-sdk-ext.kms-local": "0.27.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/mdl-mdoc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"build:clean": "tsc --build --clean && tsc --build"
},
"dependencies": {
"@sphereon/did-auth-siop-adapter": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/did-auth-siop-adapter": "0.16.1-feature.SPRIND.137.254",
"@sphereon/kmp-mdoc-core": "0.2.0-SNAPSHOT.26",
"@sphereon/pex": "5.0.0-unstable.28",
"@sphereon/pex-models": "^2.3.2",
Expand All @@ -35,8 +35,8 @@
"uuid": "^9.0.1"
},
"devDependencies": {
"@sphereon/oid4vci-client": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vci-client": "0.16.1-feature.SPRIND.137.254",
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254",
"@sphereon/ssi-express-support": "workspace:*",
"@sphereon/ssi-sdk-ext.key-manager": "0.27.0",
"@sphereon/ssi-sdk-ext.kms-local": "0.27.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/oid4vci-holder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
},
"dependencies": {
"@sphereon/kmp-mdoc-core": "0.2.0-SNAPSHOT.26",
"@sphereon/oid4vci-client": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vci-client": "0.16.1-feature.SPRIND.137.254",
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254",
"@sphereon/ssi-sdk-ext.did-utils": "0.27.0",
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.27.0",
"@sphereon/ssi-sdk-ext.jwt-service": "0.27.0",
Expand All @@ -43,7 +43,7 @@
"xstate": "^4.38.3"
},
"devDependencies": {
"@sphereon/oid4vc-common": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vc-common": "0.16.1-feature.SPRIND.137.254",
"@sphereon/ssi-sdk-ext.did-resolver-jwk": "0.27.0",
"@types/i18n-js": "^3.8.9",
"@types/lodash.memoize": "^4.1.9",
Expand Down
12 changes: 12 additions & 0 deletions packages/oid4vci-holder/src/agent/OID4VCIHolder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
AuthorizationRequestOpts,
AuthorizationServerClientOpts,
AuthorizationServerOpts,
CredentialConfigurationSupportedJwtVcJsonLdAndLdpVcV1_0_13,
CredentialDefinitionJwtVcJsonLdAndLdpVcV1_0_13,
CredentialOfferRequestWithBaseUrl,
DefaultURISchemes,
EndpointMetadataResult,
Expand Down Expand Up @@ -675,7 +677,10 @@ export class OID4VCIHolder implements IAgentPlugin {
if (!credentialTypes || credentialTypes.length === 0) {
return Promise.reject(Error('cannot determine credential id to request'))
}

const credentialDefinition = this.getCredentialDefinition(issuanceOpt)
const credentialResponse = await client.acquireCredentials({
...(credentialDefinition && { context: credentialDefinition['@context'] }),
credentialTypes,
proofCallbacks: callbacks,
format: issuanceOpt.format,
Expand Down Expand Up @@ -1127,4 +1132,11 @@ export class OID4VCIHolder implements IAgentPlugin {
}
return undefined
}

private getCredentialDefinition(issuanceOpt: IssuanceOpts): CredentialDefinitionJwtVcJsonLdAndLdpVcV1_0_13 | undefined {
if (issuanceOpt.format == 'ldp_vc' || issuanceOpt.format == 'jwt_vc_json-ld') {
return (issuanceOpt as CredentialConfigurationSupportedJwtVcJsonLdAndLdpVcV1_0_13).credential_definition
}
return undefined
}
}
6 changes: 3 additions & 3 deletions packages/oid4vci-issuer-rest-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"start:dev": "ts-node __tests__/RestAPI.ts"
},
"dependencies": {
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vci-issuer": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vci-issuer-server": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254",
"@sphereon/oid4vci-issuer": "0.16.1-feature.SPRIND.137.254",
"@sphereon/oid4vci-issuer-server": "0.16.1-feature.SPRIND.137.254",
"@sphereon/ssi-express-support": "workspace:*",
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.27.0",
"@sphereon/ssi-sdk.kv-store-temp": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/oid4vci-issuer-rest-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"generate-plugin-schema": "ts-node ../../packages/dev/bin/sphereon.js dev generate-plugin-schema"
},
"dependencies": {
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254",
"@sphereon/ssi-types": "workspace:*",
"@veramo/core": "4.2.0",
"cross-fetch": "^3.1.8"
Expand Down
2 changes: 1 addition & 1 deletion packages/oid4vci-issuer-store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"build:clean": "tsc --build --clean && tsc --build"
},
"dependencies": {
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254",
"@sphereon/ssi-sdk-ext.did-utils": "0.27.0",
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.27.0",
"@sphereon/ssi-sdk.kv-store-temp": "workspace:*",
Expand Down
4 changes: 2 additions & 2 deletions packages/oid4vci-issuer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"build:clean": "tsc --build --clean && tsc --build"
},
"dependencies": {
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vci-issuer": "0.16.1-feature.SPRIND.137.254+5674a27",
"@sphereon/oid4vci-common": "0.16.1-feature.SPRIND.137.254",
"@sphereon/oid4vci-issuer": "0.16.1-feature.SPRIND.137.254",
"@sphereon/ssi-sdk-ext.did-utils": "0.27.0",
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.27.0",
"@sphereon/ssi-sdk.agent-config": "workspace:*",
Expand Down
Loading
Loading