@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth 0.34.1-fix.170 → 0.34.1-fix.182

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,20 +4,18 @@ import {
4
4
  AuthorizationResponseState,
5
5
  AuthorizationResponseStateStatus,
6
6
  AuthorizationResponseStateWithVerifiedData,
7
- decodeUriAsJson, EncodedDcqlPresentationVpToken,
8
- VerifiedAuthorizationResponse
7
+ decodeUriAsJson,
8
+ VerifiedAuthorizationResponse,
9
9
  } from '@sphereon/did-auth-siop'
10
10
  import { getAgentResolver } from '@sphereon/ssi-sdk-ext.did-utils'
11
11
  import { shaHasher as defaultHasher } from '@sphereon/ssi-sdk.core'
12
+ import type { ImportDcqlQueryItem } from '@sphereon/ssi-sdk.pd-manager'
12
13
  import {
13
14
  AdditionalClaims,
14
15
  CredentialMapper,
15
- //decodeSdJwtVc,
16
16
  HasherSync,
17
17
  ICredentialSubject,
18
18
  IPresentation,
19
- //IProofPurpose,
20
- //IProofType,
21
19
  IVerifiableCredential,
22
20
  IVerifiablePresentation,
23
21
  JwtDecodedVerifiablePresentation,
@@ -25,7 +23,6 @@ import {
25
23
  MdocOid4vpMdocVpToken,
26
24
  OriginalVerifiablePresentation,
27
25
  SdJwtDecodedVerifiableCredential,
28
- //sha256
29
26
  } from '@sphereon/ssi-types'
30
27
  import { IAgentPlugin } from '@veramo/core'
31
28
  import { DcqlQuery } from 'dcql'
@@ -44,11 +41,11 @@ import {
44
41
  ISiopv2RPOpts,
45
42
  IUpdateRequestStateArgs,
46
43
  IVerifyAuthResponseStateArgs,
47
- schema
44
+ schema,
45
+ VerifiedDataMode,
48
46
  } from '../index'
49
47
  import { RPInstance } from '../RPInstance'
50
48
  import { ISIOPv2RP } from '../types/ISIOPv2RP'
51
- //import { jwtDecode } from 'jwt-decode'
52
49
 
53
50
  export class SIOPv2RP implements IAgentPlugin {
54
51
  private readonly opts: ISiopv2RPOpts
@@ -88,7 +85,10 @@ export class SIOPv2RP implements IAgentPlugin {
88
85
  }
89
86
 
90
87
  private async createAuthorizationRequestURI(createArgs: ICreateAuthRequestArgs, context: IRequiredContext): Promise<string> {
91
- return await this.getRPInstance({ responseRedirectURI: createArgs.responseRedirectURI, ...(createArgs.useQueryIdInstance === true && { queryId: createArgs.queryId } ) }, context)
88
+ return await this.getRPInstance(
89
+ { responseRedirectURI: createArgs.responseRedirectURI, ...(createArgs.useQueryIdInstance === true && { queryId: createArgs.queryId }) },
90
+ context,
91
+ )
92
92
  .then((rp) => rp.createAuthorizationRequestURI(createArgs, context))
93
93
  .then((URI) => URI.encodedUri)
94
94
  }
@@ -111,9 +111,7 @@ export class SIOPv2RP implements IAgentPlugin {
111
111
 
112
112
  private async siopGetRequestState(args: IGetAuthRequestStateArgs, context: IRequiredContext): Promise<AuthorizationRequestState | undefined> {
113
113
  return await this.getRPInstance({ queryId: args.queryId }, context).then((rp) =>
114
- rp.get(context).then((rp) =>
115
- rp.sessionManager.getRequestStateByCorrelationId(args.correlationId, args.errorOnNotFound)
116
- ),
114
+ rp.get(context).then((rp) => rp.sessionManager.getRequestStateByCorrelationId(args.correlationId, args.errorOnNotFound)),
117
115
  )
118
116
  }
119
117
 
@@ -130,7 +128,11 @@ export class SIOPv2RP implements IAgentPlugin {
130
128
  }
131
129
 
132
130
  const responseState = authorizationResponseState as AuthorizationResponseStateWithVerifiedData
133
- if (responseState.status === AuthorizationResponseStateStatus.VERIFIED) {
131
+ if (
132
+ responseState.status === AuthorizationResponseStateStatus.VERIFIED &&
133
+ args.includeVerifiedData &&
134
+ args.includeVerifiedData !== VerifiedDataMode.NONE
135
+ ) {
134
136
  let hasher: HasherSync | undefined
135
137
  if (
136
138
  CredentialMapper.isSdJwtEncoded(responseState.response.payload.vp_token as OriginalVerifiablePresentation) &&
@@ -138,21 +140,19 @@ export class SIOPv2RP implements IAgentPlugin {
138
140
  ) {
139
141
  hasher = defaultHasher
140
142
  }
141
-
142
- const vpToken = responseState.response.payload.vp_token && JSON.parse(responseState.response.payload.vp_token as EncodedDcqlPresentationVpToken)
143
- const claims = []
144
- for (const [key, value] of Object.entries(vpToken)) {
145
- const presentationDecoded = CredentialMapper.decodeVerifiablePresentation(
146
- value as OriginalVerifiablePresentation,
147
- //todo: later we want to conditionally pass in options for mdl-mdoc here
148
- hasher,
149
- )
150
- console.log(`presentationDecoded: ${JSON.stringify(presentationDecoded)}`)
151
-
152
- let allClaims: AdditionalClaims = {}
153
- const presentationOrClaims = this.presentationOrClaimsFrom(presentationDecoded)
154
- if ('verifiableCredential' in presentationOrClaims) {
155
- for (const credential of presentationOrClaims.verifiableCredential) {
143
+ // todo this should also include mdl-mdoc
144
+ const presentationDecoded = CredentialMapper.decodeVerifiablePresentation(
145
+ responseState.response.payload.vp_token as OriginalVerifiablePresentation,
146
+ //todo: later we want to conditionally pass in options for mdl-mdoc here
147
+ hasher,
148
+ )
149
+ switch (args.includeVerifiedData) {
150
+ case VerifiedDataMode.VERIFIED_PRESENTATION:
151
+ responseState.response.payload.verifiedData = this.presentationOrClaimsFrom(presentationDecoded)
152
+ break
153
+ case VerifiedDataMode.CREDENTIAL_SUBJECT_FLATTENED: // TODO debug cs-flat for SD-JWT
154
+ const allClaims: AdditionalClaims = {}
155
+ for (const credential of this.presentationOrClaimsFrom(presentationDecoded).verifiableCredential || []) {
156
156
  const vc = credential as IVerifiableCredential
157
157
  const schemaValidationResult = await context.agent.cvVerifySchema({
158
158
  credential,
@@ -175,90 +175,10 @@ export class SIOPv2RP implements IAgentPlugin {
175
175
  allClaims[key] = value
176
176
  }
177
177
  })
178
-
179
- claims.push({
180
- id: key,
181
- type: vc.type[0],
182
- claims: allClaims
183
- })
184
- }
185
- } else {
186
- claims.push({
187
- id: key,
188
- type: (presentationDecoded as SdJwtDecodedVerifiableCredential).decodedPayload.vct,
189
- claims: presentationOrClaims
190
- })
191
- }
192
- }
193
-
194
- // const claimsPromises = responseState.response.payload.vp_token && JSON.parse(responseState.response.payload.vp_token as EncodedDcqlPresentationVpToken)
195
- // .map(async (presentation: OriginalVerifiablePresentation) => {
196
- // const presentationDecoded = CredentialMapper.decodeVerifiablePresentation(
197
- // presentation,
198
- // //todo: later we want to conditionally pass in options for mdl-mdoc here
199
- // hasher,
200
- // )
201
- //
202
- //
203
- //
204
- // return {
205
- // id: presentationDecoded.id
206
- // }
207
- //
208
- // })
209
-
210
- // // todo this should also include mdl-mdoc
211
- // const presentationDecoded = CredentialMapper.decodeVerifiablePresentation(
212
- // responseState.response.payload.vp_token as OriginalVerifiablePresentation,
213
- // //todo: later we want to conditionally pass in options for mdl-mdoc here
214
- // hasher,
215
- // )
216
- // console.log(`presentationDecoded: ${JSON.stringify(presentationDecoded)}`)
217
-
218
- responseState.verifiedData = {
219
- ...(responseState.response.payload.vp_token && {
220
- authorization_response: {
221
- vp_token: typeof responseState.response.payload.vp_token === 'string' // TODO we might not need this string check
222
- ? JSON.parse(responseState.response.payload.vp_token)
223
- : responseState.response.payload.vp_token
224
178
  }
225
- }),
226
- credential_claims: claims//(this.presentationOrClaimsFrom(presentationDecoded).verifiableCredential || []).map()
179
+ responseState.verifiedData = allClaims
180
+ break
227
181
  }
228
-
229
- // switch (args.includeVerifiedData) {
230
- // case VerifiedDataMode.VERIFIED_PRESENTATION:
231
- // responseState.response.payload.verifiedData = this.presentationOrClaimsFrom(presentationDecoded)
232
- // break
233
- // case VerifiedDataMode.CREDENTIAL_SUBJECT_FLATTENED: // TODO debug cs-flat for SD-JWT
234
- // const allClaims: AdditionalClaims = {}
235
- // for (const credential of this.presentationOrClaimsFrom(presentationDecoded).verifiableCredential || []) {
236
- // const vc = credential as IVerifiableCredential
237
- // const schemaValidationResult = await context.agent.cvVerifySchema({
238
- // credential,
239
- // hasher,
240
- // validationPolicy: rpInstance.rpOptions.verificationPolicies?.schemaValidation,
241
- // })
242
- // if (!schemaValidationResult.result) {
243
- // responseState.status = AuthorizationResponseStateStatus.ERROR
244
- // responseState.error = new Error(schemaValidationResult.error)
245
- // return responseState
246
- // }
247
- //
248
- // const credentialSubject = vc.credentialSubject as ICredentialSubject & AdditionalClaims
249
- // if (!('id' in allClaims)) {
250
- // allClaims['id'] = credentialSubject.id
251
- // }
252
- //
253
- // Object.entries(credentialSubject).forEach(([key, value]) => {
254
- // if (!(key in allClaims)) {
255
- // allClaims[key] = value
256
- // }
257
- // })
258
- // }
259
- // responseState.verifiedData = allClaims
260
- // break
261
- // }
262
182
  }
263
183
  return responseState
264
184
  }
@@ -269,12 +189,11 @@ export class SIOPv2RP implements IAgentPlugin {
269
189
  | IVerifiablePresentation
270
190
  | SdJwtDecodedVerifiableCredential
271
191
  | MdocOid4vpMdocVpToken
272
- | MdocDeviceResponse
273
- ): AdditionalClaims | IPresentation => {
274
- return CredentialMapper.isSdJwtDecodedCredential(presentationDecoded)
192
+ | MdocDeviceResponse,
193
+ ): AdditionalClaims | IPresentation =>
194
+ CredentialMapper.isSdJwtDecodedCredential(presentationDecoded)
275
195
  ? presentationDecoded.decodedPayload
276
196
  : CredentialMapper.toUniformPresentation(presentationDecoded as OriginalVerifiablePresentation)
277
- }
278
197
 
279
198
  private async siopUpdateRequestState(args: IUpdateRequestStateArgs, context: IRequiredContext): Promise<AuthorizationRequestState> {
280
199
  if (args.state !== 'authorization_request_created') {
@@ -311,7 +230,7 @@ export class SIOPv2RP implements IAgentPlugin {
311
230
  rp.get(context).then((rp) =>
312
231
  rp.verifyAuthorizationResponse(authResponse, {
313
232
  correlationId: args.correlationId,
314
- ...(args.dcqlQueryPayload ? { dcqlQuery: args.dcqlQueryPayload.dcqlQuery } : {}),
233
+ ...(args.dcqlQuery ? { dcqlQuery: args.dcqlQuery } : {}),
315
234
  audience: args.audience,
316
235
  }),
317
236
  ),
@@ -319,33 +238,18 @@ export class SIOPv2RP implements IAgentPlugin {
319
238
  }
320
239
 
321
240
  private async siopImportDefinitions(args: ImportDefinitionsArgs, context: IRequiredContext): Promise<void> {
322
- const { queries, tenantId, version, versionControlMode } = args
241
+ const { importItems, tenantId, version, versionControlMode } = args
323
242
  await Promise.all(
324
- queries.map(async (definitionPair) => {
325
- const definitionPayload = definitionPair.definitionPayload
326
- if (!definitionPayload && !definitionPair.dcqlPayload) {
327
- return Promise.reject(Error('Either dcqlPayload or definitionPayload must be suppplied'))
328
- }
329
-
330
- let definitionId: string
331
- if (definitionPair.dcqlPayload) {
332
- DcqlQuery.validate(definitionPair.dcqlPayload.dcqlQuery)
333
- console.log(`persisting DCQL definition ${definitionPair.dcqlPayload.queryId} with versionControlMode ${versionControlMode}`)
334
- definitionId = definitionPair.dcqlPayload.queryId
335
- }
336
- if (definitionPayload) {
337
- await context.agent.pexValidateDefinition({ definition: definitionPayload })
338
- console.log(`persisting PEX definition ${definitionPayload.id} / ${definitionPayload.name} with versionControlMode ${versionControlMode}`)
339
- definitionId = definitionPayload.id
340
- }
243
+ importItems.map(async (importItem: ImportDcqlQueryItem) => {
244
+ DcqlQuery.validate(importItem.query)
245
+ console.log(`persisting DCQL definition ${importItem.queryId} with versionControlMode ${versionControlMode}`)
341
246
 
342
247
  return context.agent.pdmPersistDefinition({
343
248
  definitionItem: {
344
- definitionId: definitionId!,
249
+ queryId: importItem.queryId!,
345
250
  tenantId: tenantId,
346
251
  version: version,
347
- definitionPayload,
348
- dcqlPayload: definitionPair.dcqlPayload,
252
+ query: importItem.query,
349
253
  },
350
254
  opts: { versionControlMode: versionControlMode },
351
255
  })
package/src/functions.ts CHANGED
@@ -28,12 +28,7 @@ import {
28
28
  } from '@sphereon/ssi-sdk-ext.identifier-resolution'
29
29
  import { JwtCompactResult } from '@sphereon/ssi-sdk-ext.jwt-service'
30
30
  import { IVerifySdJwtPresentationResult } from '@sphereon/ssi-sdk.sd-jwt'
31
- import {
32
- CredentialMapper,
33
- HasherSync,
34
- OriginalVerifiableCredential,
35
- PresentationSubmission
36
- } from '@sphereon/ssi-types'
31
+ import { CredentialMapper, HasherSync, OriginalVerifiableCredential, PresentationSubmission } from '@sphereon/ssi-types'
37
32
  import { IVerifyCallbackArgs, IVerifyCredentialResult, VerifyCallback } from '@sphereon/wellknown-dids-client'
38
33
  import { TKeyType } from '@veramo/core'
39
34
  import { JWTVerifyOptions } from 'did-jwt'
@@ -72,7 +67,7 @@ export function getPresentationVerificationCallback(
72
67
  ): Promise<PresentationVerificationResult> {
73
68
  if (CredentialMapper.isSdJwtEncoded(args)) {
74
69
  const result: IVerifySdJwtPresentationResult = await context.agent.verifySdJwtPresentation({
75
- presentation: args
70
+ presentation: args,
76
71
  })
77
72
  // fixme: investigate the correct way to handle this
78
73
  return { verified: !!result.payload }
@@ -120,7 +115,7 @@ export async function createRPBuilder(args: {
120
115
  const presentationDefinitionItems = await context.agent.pdmGetDefinitions({
121
116
  filter: [
122
117
  {
123
- definitionId: pexOpts.queryId,
118
+ queryId: pexOpts.queryId,
124
119
  version: pexOpts.version,
125
120
  tenantId: pexOpts.tenantId,
126
121
  },
@@ -202,9 +197,11 @@ export async function createRPBuilder(args: {
202
197
  builder.withEntityId(oidfOpts.identifier, PropertyTarget.REQUEST_OBJECT)
203
198
  } else {
204
199
  const resolution = await context.agent.identifierManagedGet(identifierOpts.idOpts)
205
- const clientId: string = rpOpts.clientMetadataOpts?.client_id ?? resolution.issuer ?? (isManagedIdentifierDidResult(resolution) ? resolution.did : resolution.jwkThumbprint)
206
- const clientIdPrefixed = prefixClientId(clientId)
207
- builder.withClientId(clientIdPrefixed, PropertyTarget.REQUEST_OBJECT)
200
+ const clientId: string = rpOpts.clientMetadataOpts?.client_id ??
201
+ resolution.issuer ?? (isManagedIdentifierDidResult(resolution) ? resolution.did : resolution.jwkThumbprint)
202
+ const clientIdPrefixed = prefixClientId(clientId)
203
+ builder.withClientId(clientIdPrefixed, PropertyTarget.REQUEST_OBJECT
204
+ )
208
205
  }
209
206
 
210
207
  if (hasher) {
@@ -24,13 +24,14 @@ import { ExternalIdentifierOIDFEntityIdOpts, IIdentifierResolution, ManagedIdent
24
24
  import { IJwtService } from '@sphereon/ssi-sdk-ext.jwt-service'
25
25
  import { ICredentialValidation, SchemaValidation } from '@sphereon/ssi-sdk.credential-validation'
26
26
  import { ImDLMdoc } from '@sphereon/ssi-sdk.mdl-mdoc'
27
- import { IPDManager, VersionControlMode } from '@sphereon/ssi-sdk.pd-manager'
27
+ import { ImportDcqlQueryItem, IPDManager, VersionControlMode } from '@sphereon/ssi-sdk.pd-manager'
28
28
  import { IPresentationExchange } from '@sphereon/ssi-sdk.presentation-exchange'
29
29
  import { ISDJwtPlugin } from '@sphereon/ssi-sdk.sd-jwt'
30
30
  import { AuthorizationRequestStateStatus } from '@sphereon/ssi-sdk.siopv2-oid4vp-common'
31
- import { DcqlQueryPayload, HasherSync } from '@sphereon/ssi-types'
31
+ import { HasherSync } from '@sphereon/ssi-types'
32
32
  import { VerifyCallback } from '@sphereon/wellknown-dids-client'
33
33
  import { IAgentContext, ICredentialVerifier, IDIDManager, IKeyManager, IPluginMethodMap, IResolver } from '@veramo/core'
34
+ import { DcqlQuery } from 'dcql'
34
35
 
35
36
  import { Resolvable } from 'did-resolver'
36
37
  import { EventEmitter } from 'events'
@@ -89,11 +90,11 @@ export interface IGetAuthResponseStateArgs {
89
90
  queryId?: string
90
91
  errorOnNotFound?: boolean
91
92
  progressRequestStateTo?: AuthorizationRequestStateStatus
92
- //includeVerifiedData?: VerifiedDataMode
93
+ includeVerifiedData?: VerifiedDataMode
93
94
  }
94
95
 
95
96
  export interface IUpdateRequestStateArgs {
96
- queryId?: string
97
+ queryId: string
97
98
  correlationId: string
98
99
  state: AuthorizationRequestStateStatus
99
100
  error?: string
@@ -109,16 +110,10 @@ export interface IVerifyAuthResponseStateArgs {
109
110
  queryId?: string
110
111
  correlationId: string
111
112
  audience?: string
112
- dcqlQueryPayload?: DcqlQueryPayload
113
+ dcqlQuery?: DcqlQuery
113
114
  }
114
-
115
- export interface IDefinitionPair {
116
- definitionPayload?: IPresentationDefinition
117
- dcqlPayload?: DcqlQueryPayload
118
- }
119
-
120
115
  export interface ImportDefinitionsArgs {
121
- queries: Array<IDefinitionPair>
116
+ importItems: Array<ImportDcqlQueryItem>
122
117
  tenantId?: string
123
118
  version?: string
124
119
  versionControlMode?: VersionControlMode