Skip to content

Commit 42b7f50

Browse files
committed
resolves PR threads
Signed-off-by: nodirbek.parpibaev <nodirbek.parpibaev@dsr-corporation.com>
1 parent ef17328 commit 42b7f50

9 files changed

Lines changed: 109 additions & 94 deletions

File tree

heka-identity-service-web-ui/src/entities/Presentation/model/services/requestPresentation.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ const requestOpenId4VcPresentation = async (
9090
params.requestedAttributes ??
9191
params.schema.fields?.map((schema) => schema.name) ??
9292
[],
93+
doctype: params.schema.name,
94+
namespace: params.schema.name,
9395
});
9496
const response = await api.post<RequestOpenIdPresentationResponse>(
9597
agencyEndpoints.requestOpenIdPresentation,

heka-identity-service-web-ui/src/entities/Presentation/model/utils/presentation-request.ts

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ export interface BuildOpenIdPresentationRequestParams {
1717
name: string;
1818
attributes: Array<string>;
1919
purpose?: string;
20+
/** doctype for mso_mdoc credentials (e.g. 'org.iso.18013.5.1.mDL') */
21+
doctype?: string;
22+
/** namespace for mso_mdoc claim paths (e.g. 'org.iso.18013.5.1') */
23+
namespace?: string;
2024
}
2125

2226
export const buildSdJwtPresentationRequest = ({
@@ -93,28 +97,46 @@ export const buildJwtJsonPresentationRequest = ({
9397
};
9498
};
9599

100+
const MDL_DOCTYPE = 'org.iso.18013.5.1.mDL'
101+
const MDL_NAMESPACE = 'org.iso.18013.5.1'
102+
const MDL_ALG = ['ES256', 'ES384', 'ES512', 'EdDSA', 'ESB256', 'ESB320', 'ESB384', 'ESB512']
103+
96104
export const buildMsoMdocPresentationRequest = ({
97105
id,
98106
did,
107+
name,
99108
attributes,
109+
purpose,
110+
doctype = MDL_DOCTYPE,
111+
namespace = MDL_NAMESPACE,
100112
}: BuildOpenIdPresentationRequestParams) => {
101113
return {
102114
publicVerifierId: id,
103115
requestSigner: {
104116
method: 'did',
105117
did: did,
106118
},
107-
dcql: {
108-
query: {
109-
credentials: [
119+
presentationExchange: {
120+
definition: {
121+
id: v4(),
122+
name,
123+
input_descriptors: [
110124
{
111-
format: 'mso_mdoc',
112-
id: 'mdl-credential',
113-
meta: { doctype_value: 'org.iso.18013.5.1.mDL' },
114-
claims: attributes.map((attribute) => ({
115-
namespace: 'org.iso.18013.5.1',
116-
claim_name: attribute,
117-
})),
125+
id: doctype,
126+
format: {
127+
mso_mdoc: {
128+
alg: MDL_ALG,
129+
},
130+
},
131+
constraints: {
132+
limit_disclosure: 'required',
133+
fields: attributes.map((attribute) => ({
134+
path: [`$['${namespace}']['${attribute}']`],
135+
intent_to_retain: false,
136+
})),
137+
},
138+
name,
139+
purpose: purpose ?? 'To obtain credential data',
118140
},
119141
],
120142
},

heka-identity-service-web-ui/src/entities/Schema/model/utils/schema.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ interface OpenId4VcMsoMdocCredentialSchema {
3939
format: Openid4CredentialFormat.MsoMdoc;
4040
id: string;
4141
doctype: string;
42+
claims?: Record<string, unknown>;
4243
}
4344

4445
export type OpenId4CredentialSchema =
@@ -81,7 +82,7 @@ export const convertOpenIdSchema = (schema: OpenId4CredentialSchema) => {
8182
id: schema.id,
8283
format: schema.format,
8384
doctype: schema.doctype,
84-
attributes: [],
85+
attributes: Object.keys(schema.claims ?? {}),
8586
};
8687
}
8788
};

heka-identity-service/src/common/notification/notification-events.listener.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,14 @@ export class NotificationEventsListener implements OnModuleInit, OnModuleDestroy
8080
switch (event.type) {
8181
case ConnectionEventTypes.ConnectionDidRotated:
8282
case ConnectionEventTypes.ConnectionStateChanged: {
83-
return new ConnectionStateChangeDto(event as any)
83+
return new ConnectionStateChangeDto(event)
8484
}
8585
case CredentialEventTypes.CredentialStateChanged:
8686
case CredentialEventTypes.RevocationNotificationReceived: {
87-
return new CredentialStateChangeDto(event as any)
87+
return new CredentialStateChangeDto(event)
8888
}
8989
case ProofEventTypes.ProofStateChanged: {
90-
return new ProofStateChangeDto(event as any)
90+
return new ProofStateChangeDto(event)
9191
}
9292
case OpenId4VcIssuerEvents.IssuanceSessionStateChanged: {
9393
return new OpenidIssueStateChangeDto(event)

heka-identity-service/src/credential-v2/credential-v2.service.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ export class CredentialV2Service {
235235
return {
236236
format: OpenId4VciCredentialFormatProfile.MsoMdoc,
237237
credentialSupportedId: (registration.credentials as Oid4vcCredentials).supportedCredentialId,
238-
namespaces: { 'org.iso.18013.5.1': payload },
238+
namespaces: { [template.schema.name ?? 'org.iso.18013.5.1']: payload },
239239
} as OpenId4VcIssuanceSessionCreateOfferMsoMdocCredentialOptions
240240
}
241241
throw new Error(`Unsupported OID4VC credential format: ${template.credentialFormat}`)
@@ -280,21 +280,37 @@ export class CredentialV2Service {
280280
template: GetVerificationTemplateResponse,
281281
registration: SchemaRegistration,
282282
): OpenId4VcVerificationSessionCreateRequestDto {
283+
const MDL_ALG = ['ES256', 'ES384', 'ES512', 'EdDSA', 'ESB256', 'ESB320', 'ESB384', 'ESB512']
284+
283285
if (template.credentialFormat === OpenId4VcCredentialFormat.MsoMdoc) {
286+
const doctype = template.schema.name ?? 'org.iso.18013.5.1.mDL'
287+
const namespace = template.schema.name ?? 'org.iso.18013.5.1'
284288
return {
285289
publicVerifierId: registration.did,
286290
requestSigner: {
287291
method: 'did',
288292
did: registration.did,
289293
},
290-
dcql: {
291-
query: {
292-
credentials: [
294+
presentationExchange: {
295+
definition: {
296+
id: v4(),
297+
name: template.name,
298+
input_descriptors: [
293299
{
294-
format: 'mso_mdoc',
295-
id: 'mdl-credential',
296-
meta: { doctype_value: 'org.iso.18013.5.1.mDL' },
297-
claims: fields.map((field) => ({ namespace: 'org.iso.18013.5.1', claim_name: field })),
300+
id: doctype,
301+
format: {
302+
mso_mdoc: {
303+
alg: MDL_ALG,
304+
},
305+
},
306+
constraints: {
307+
limit_disclosure: 'required',
308+
fields: fields.map((field) => ({
309+
path: [`$['${namespace}']['${field}']`],
310+
intent_to_retain: false,
311+
})),
312+
},
313+
name: template.name,
298314
},
299315
],
300316
},

heka-identity-service/src/openid4vc/issuer/dto/common/credential.ts

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -160,14 +160,14 @@ export class OpenId4VciSdJwtCredentialSupportedWithId extends OpenId4VciCredenti
160160
public static fromOpenIdVcCredentialSupportedWithId(
161161
record: CredoCredentialConfigurationSupportedWithId,
162162
): OpenId4VciSdJwtCredentialSupportedWithId {
163-
const r = record as SdJwtConfigRecord
163+
const sdJwtRecord = record as SdJwtConfigRecord
164164
return new OpenId4VciSdJwtCredentialSupportedWithId({
165-
id: r.id,
165+
id: sdJwtRecord.id,
166166
format: CredentialFormat.SdJwt,
167-
vct: r.vct,
168-
claims: r.claims,
169-
order: r.order,
170-
display: r.display,
167+
vct: sdJwtRecord.vct,
168+
claims: sdJwtRecord.claims,
169+
order: sdJwtRecord.order,
170+
display: sdJwtRecord.display,
171171
})
172172
}
173173
}
@@ -191,12 +191,12 @@ export class OpenId4VciJwtVcJsonCredentialSupportedWithId extends OpenId4VciCred
191191
public static fromOpenIdVcCredentialSupportedWithId(
192192
record: CredoCredentialConfigurationSupportedWithId,
193193
): OpenId4VciJwtVcJsonCredentialSupportedWithId {
194-
const r = record as JwtVcJsonConfigRecord
194+
const jwtVcJsonRecord = record as JwtVcJsonConfigRecord
195195
return new OpenId4VciJwtVcJsonCredentialSupportedWithId({
196-
id: r.id,
196+
id: jwtVcJsonRecord.id,
197197
format: CredentialFormat.JwtJson,
198-
credential_definition: r.credential_definition,
199-
display: r.display,
198+
credential_definition: jwtVcJsonRecord.credential_definition,
199+
display: jwtVcJsonRecord.display,
200200
})
201201
}
202202
}
@@ -220,12 +220,12 @@ export class OpenId4VciJwtVcJsonLdCredentialSupportedWithId extends OpenId4VciCr
220220
public static fromOpenIdVcCredentialSupportedWithId(
221221
record: CredoCredentialConfigurationSupportedWithId,
222222
): OpenId4VciJwtVcJsonLdCredentialSupportedWithId {
223-
const r = record as JwtVcJsonLdConfigRecord
223+
const jwtVcJsonLdRecord = record as JwtVcJsonLdConfigRecord
224224
return new OpenId4VciJwtVcJsonLdCredentialSupportedWithId({
225-
id: r.id,
225+
id: jwtVcJsonLdRecord.id,
226226
format: CredentialFormat.JwtVcJsonLd,
227-
credential_definition: r.credential_definition,
228-
display: r.display,
227+
credential_definition: jwtVcJsonLdRecord.credential_definition,
228+
display: jwtVcJsonLdRecord.display,
229229
})
230230
}
231231
}
@@ -249,12 +249,12 @@ export class OpenId4VciLdpVcCredentialSupportedWithId extends OpenId4VciCredenti
249249
public static fromOpenIdVcCredentialSupportedWithId(
250250
record: CredoCredentialConfigurationSupportedWithId,
251251
): OpenId4VciLdpVcCredentialSupportedWithId {
252-
const r = record as LdpVcConfigRecord
252+
const ldpVcRecord = record as LdpVcConfigRecord
253253
return new OpenId4VciLdpVcCredentialSupportedWithId({
254-
id: r.id,
254+
id: ldpVcRecord.id,
255255
format: CredentialFormat.LdpVc,
256-
credential_definition: r.credential_definition,
257-
display: r.display,
256+
credential_definition: ldpVcRecord.credential_definition,
257+
display: ldpVcRecord.display,
258258
})
259259
}
260260
}
@@ -279,12 +279,12 @@ export class OpenId4VciMsoMdocCredentialSupportedWithId extends OpenId4VciCreden
279279
public static fromOpenIdVcCredentialSupportedWithId(
280280
record: CredoCredentialConfigurationSupportedWithId,
281281
): OpenId4VciMsoMdocCredentialSupportedWithId {
282-
const r = record as MsoMdocConfigRecord
282+
const msoMdocRecord = record as MsoMdocConfigRecord
283283
return new OpenId4VciMsoMdocCredentialSupportedWithId({
284-
id: r.id,
284+
id: msoMdocRecord.id,
285285
format: CredentialFormat.MsoMdoc,
286-
doctype: r.doctype,
287-
display: r.display,
286+
doctype: msoMdocRecord.doctype,
287+
display: msoMdocRecord.display,
288288
})
289289
}
290290
}

heka-identity-service/src/openid4vc/verification-sessions/dto/credential-verification.dto.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -65,27 +65,6 @@ export class OpenId4VcVerificationSessionCreateRequestDto {
6565
definition: DifPresentationExchangeDefinitionV2
6666
}
6767

68-
/**
69-
* A Digital Credentials Query Language (DCQL) query to request credentials.
70-
* Used for mDL (mso_mdoc) and other DCQL-compatible credential formats.
71-
*
72-
* @example
73-
* {
74-
* "query": {
75-
* "credentials": [{
76-
* "format": "mso_mdoc",
77-
* "id": "mdl-credential",
78-
* "meta": { "doctype_value": "org.iso.18013.5.1.mDL" },
79-
* "claims": [{ "namespace": "org.iso.18013.5.1", "claim_name": "family_name" }]
80-
* }]
81-
* }
82-
* }
83-
*/
84-
@ApiPropertyOptional()
85-
@IsOptional()
86-
public dcql?: {
87-
query: Record<string, unknown>
88-
}
8968
}
9069

9170
export class OpenId4VcVerificationSessionCreateRequestResponse {

heka-identity-service/src/openid4vc/verification-sessions/verification-session.service.ts

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { W3cJwtVerifiablePresentation } from '@credo-ts/core'
22

3-
import { DcqlQuery, MdocDeviceResponse, SdJwtVc, VerifiablePresentation, W3cCredentialSubject } from '@credo-ts/core'
3+
import { MdocDeviceResponse, SdJwtVc, VerifiablePresentation, W3cCredentialSubject } from '@credo-ts/core'
44
import { OpenId4VcVerificationSessionRepository, OpenId4VcVerificationSessionState } from '@credo-ts/openid4vc'
55
import { Injectable, InternalServerErrorException, UnprocessableEntityException } from '@nestjs/common'
66

@@ -35,8 +35,7 @@ export class OpenId4VcVerificationSessionService {
3535
},
3636
verifierId: req.publicVerifierId,
3737
presentationExchange: req.presentationExchange,
38-
dcql: req.dcql as { query: DcqlQuery } | undefined,
39-
version: req.dcql ? 'v1.draft24' : 'v1.draft21',
38+
version: 'v1.draft21',
4039
})
4140

4241
return {
@@ -86,33 +85,30 @@ export class OpenId4VcVerificationSessionService {
8685
const verifiedAuthorizationResponse =
8786
await tenantAgent.modules.openId4VcVerifier.getVerifiedAuthorizationResponse(verificationSessionId)
8887

89-
if (verifiedAuthorizationResponse.presentationExchange?.presentations.length) {
90-
const presentation = verifiedAuthorizationResponse.presentationExchange?.presentations[0]
91-
if (OpenId4VcVerificationSessionService.isSdJwtPresentation(presentation)) {
92-
const { vct, cnf, iss, iat, ...attributes } = presentation.prettyClaims
93-
sharedAttributes = attributes
94-
} else if (OpenId4VcVerificationSessionService.isJwtVcJsonPresentation(presentation)) {
95-
const credentialSubject =
96-
presentation.presentation.verifiableCredential instanceof Array
97-
? presentation.presentation.verifiableCredential?.[0].credentialSubject
98-
: presentation.presentation.verifiableCredential.credentialSubject
99-
sharedAttributes = (credentialSubject as W3cCredentialSubject).claims
100-
}
101-
} else if (verifiedAuthorizationResponse.dcql?.presentations) {
102-
const presentations = Object.values(verifiedAuthorizationResponse.dcql.presentations)
103-
const firstPresentation = presentations[0]
104-
if (firstPresentation && OpenId4VcVerificationSessionService.isMdocPresentation(firstPresentation as VerifiablePresentation)) {
105-
const doc = (firstPresentation as MdocDeviceResponse).documents[0]
106-
if (doc) {
107-
sharedAttributes = Object.values(doc.issuerSignedNamespaces).reduce<Record<string, unknown>>(
108-
(acc, ns) => ({ ...acc, ...ns }),
109-
{},
110-
)
111-
}
112-
}
113-
} else {
88+
const presentations = verifiedAuthorizationResponse.presentationExchange?.presentations
89+
if (!presentations?.length) {
11490
throw new InternalServerErrorException('Presentation is missing')
11591
}
92+
93+
const presentation = presentations[0]
94+
if (OpenId4VcVerificationSessionService.isSdJwtPresentation(presentation)) {
95+
const { vct, cnf, iss, iat, ...attributes } = presentation.prettyClaims
96+
sharedAttributes = attributes
97+
} else if (OpenId4VcVerificationSessionService.isJwtVcJsonPresentation(presentation)) {
98+
const credentialSubject =
99+
presentation.presentation.verifiableCredential instanceof Array
100+
? presentation.presentation.verifiableCredential?.[0].credentialSubject
101+
: presentation.presentation.verifiableCredential.credentialSubject
102+
sharedAttributes = (credentialSubject as W3cCredentialSubject).claims
103+
} else if (OpenId4VcVerificationSessionService.isMdocPresentation(presentation)) {
104+
const doc = presentation.documents[0]
105+
if (doc) {
106+
sharedAttributes = Object.values(doc.issuerSignedNamespaces).reduce<Record<string, unknown>>(
107+
(acc, ns) => ({ ...acc, ...ns }),
108+
{},
109+
)
110+
}
111+
}
116112
}
117113

118114
return OpenId4VcVerificationSessionRecordDto.fromOpenId4VcVerificationSessionRecord(

heka-identity-service/src/utils/aries/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,4 @@ export const buildAriesCredential = ({
7979
}
8080
}
8181
}
82-
throw new Error(`Unsupported Aries credential format: ${format}`)
8382
}

0 commit comments

Comments
 (0)