@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth 0.34.1-feature.SSISDK.45.94 → 0.34.1-feature.SSISDK.46.151

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.
@@ -22,6 +22,7 @@ import {
22
22
  SdJwtDecodedVerifiableCredential,
23
23
  } from '@sphereon/ssi-types'
24
24
  import { IAgentPlugin } from '@veramo/core'
25
+ import { DcqlQuery } from 'dcql'
25
26
  import {
26
27
  AuthorizationResponseStateWithVerifiedData,
27
28
  IAuthorizationRequestPayloads,
@@ -42,10 +43,8 @@ import {
42
43
  VerifiedDataMode,
43
44
  } from '../index'
44
45
  import { RPInstance } from '../RPInstance'
45
-
46
46
  import { ISIOPv2RP } from '../types/ISIOPv2RP'
47
47
  import { shaHasher as defaultHasher } from '@sphereon/ssi-sdk.core'
48
- import { DcqlQuery } from 'dcql'
49
48
 
50
49
  export class SIOPv2RP implements IAgentPlugin {
51
50
  private readonly opts: ISiopv2RPOpts
@@ -85,7 +84,7 @@ export class SIOPv2RP implements IAgentPlugin {
85
84
  }
86
85
 
87
86
  private async createAuthorizationRequestURI(createArgs: ICreateAuthRequestArgs, context: IRequiredContext): Promise<string> {
88
- return await this.getRPInstance({ definitionId: createArgs.definitionId, responseRedirectURI: createArgs.responseRedirectURI }, context)
87
+ return await this.getRPInstance({ responseRedirectURI: createArgs.responseRedirectURI, ...(createArgs.useQueryIdInstance === true && { queryId: createArgs.queryId } ) }, context)
89
88
  .then((rp) => rp.createAuthorizationRequestURI(createArgs, context))
90
89
  .then((URI) => URI.encodedUri)
91
90
  }
@@ -94,21 +93,23 @@ export class SIOPv2RP implements IAgentPlugin {
94
93
  createArgs: ICreateAuthRequestArgs,
95
94
  context: IRequiredContext,
96
95
  ): Promise<IAuthorizationRequestPayloads> {
97
- return await this.getRPInstance({ definitionId: createArgs.definitionId }, context)
96
+ return await this.getRPInstance({ queryId: createArgs.queryId }, context)
98
97
  .then((rp) => rp.createAuthorizationRequest(createArgs, context))
99
98
  .then(async (request) => {
100
99
  const authRequest: IAuthorizationRequestPayloads = {
101
100
  authorizationRequest: request.payload,
102
101
  requestObject: await request.requestObjectJwt(),
103
- requestObjectDecoded: await request.requestObject?.getPayload(),
102
+ requestObjectDecoded: request.requestObject?.getPayload(),
104
103
  }
105
104
  return authRequest
106
105
  })
107
106
  }
108
107
 
109
108
  private async siopGetRequestState(args: IGetAuthRequestStateArgs, context: IRequiredContext): Promise<AuthorizationRequestState | undefined> {
110
- return await this.getRPInstance({ definitionId: args.definitionId }, context).then((rp) =>
111
- rp.get(context).then((rp) => rp.sessionManager.getRequestStateByCorrelationId(args.correlationId, args.errorOnNotFound)),
109
+ return await this.getRPInstance({ queryId: args.queryId }, context).then((rp) =>
110
+ rp.get(context).then((rp) =>
111
+ rp.sessionManager.getRequestStateByCorrelationId(args.correlationId, args.errorOnNotFound)
112
+ ),
112
113
  )
113
114
  }
114
115
 
@@ -116,7 +117,7 @@ export class SIOPv2RP implements IAgentPlugin {
116
117
  args: IGetAuthResponseStateArgs,
117
118
  context: IRequiredContext,
118
119
  ): Promise<AuthorizationResponseStateWithVerifiedData | undefined> {
119
- const rpInstance: RPInstance = await this.getRPInstance({ definitionId: args.definitionId }, context)
120
+ const rpInstance: RPInstance = await this.getRPInstance({ queryId: args.queryId }, context)
120
121
  const authorizationResponseState: AuthorizationResponseState | undefined = await rpInstance
121
122
  .get(context)
122
123
  .then((rp) => rp.sessionManager.getResponseStateByCorrelationId(args.correlationId, args.errorOnNotFound))
@@ -193,10 +194,10 @@ export class SIOPv2RP implements IAgentPlugin {
193
194
  : CredentialMapper.toUniformPresentation(presentationDecoded as OriginalVerifiablePresentation)
194
195
 
195
196
  private async siopUpdateRequestState(args: IUpdateRequestStateArgs, context: IRequiredContext): Promise<AuthorizationRequestState> {
196
- if (args.state !== 'sent') {
197
- throw Error(`Only 'sent' status is supported for this method at this point`)
197
+ if (args.state !== 'authorization_request_created') {
198
+ throw Error(`Only 'authorization_request_created' status is supported for this method at this point`)
198
199
  }
199
- return await this.getRPInstance({ definitionId: args.definitionId }, context)
200
+ return await this.getRPInstance({ queryId: args.queryId }, context)
200
201
  // todo: In the SIOP library we need to update the signal method to be more like this method
201
202
  .then((rp) =>
202
203
  rp.get(context).then(async (rp) => {
@@ -210,7 +211,7 @@ export class SIOPv2RP implements IAgentPlugin {
210
211
  }
211
212
 
212
213
  private async siopDeleteState(args: IGetAuthResponseStateArgs, context: IRequiredContext): Promise<boolean> {
213
- return await this.getRPInstance({ definitionId: args.definitionId }, context)
214
+ return await this.getRPInstance({ queryId: args.queryId }, context)
214
215
  .then((rp) => rp.get(context).then((rp) => rp.sessionManager.deleteStateForCorrelationId(args.correlationId)))
215
216
  .then(() => true)
216
217
  }
@@ -223,11 +224,11 @@ export class SIOPv2RP implements IAgentPlugin {
223
224
  typeof args.authorizationResponse === 'string'
224
225
  ? (decodeUriAsJson(args.authorizationResponse) as AuthorizationResponsePayload)
225
226
  : args.authorizationResponse
226
- return await this.getRPInstance({ definitionId: args.definitionId }, context).then((rp) =>
227
+ return await this.getRPInstance({ queryId: args.queryId }, context).then((rp) =>
227
228
  rp.get(context).then((rp) =>
228
229
  rp.verifyAuthorizationResponse(authResponse, {
229
230
  correlationId: args.correlationId,
230
- ...(args.dcqlQuery ? { dcqlQuery: args.dcqlQuery as DcqlQuery } : {}), // TODO BEFORE PR, check compatibility and whether we can remove local type
231
+ ...(args.dcqlQueryPayload ? { dcqlQuery: args.dcqlQueryPayload.dcqlQuery } : {}),
231
232
  audience: args.audience,
232
233
  }),
233
234
  ),
@@ -235,15 +236,29 @@ export class SIOPv2RP implements IAgentPlugin {
235
236
  }
236
237
 
237
238
  private async siopImportDefinitions(args: ImportDefinitionsArgs, context: IRequiredContext): Promise<void> {
238
- const { definitions, tenantId, version, versionControlMode } = args
239
+ const { queries, tenantId, version, versionControlMode } = args
239
240
  await Promise.all(
240
- definitions.map(async (definitionPair) => {
241
+ queries.map(async (definitionPair) => {
241
242
  const definitionPayload = definitionPair.definitionPayload
242
- await context.agent.pexValidateDefinition({ definition: definitionPayload })
243
+ if (!definitionPayload && !definitionPair.dcqlPayload) {
244
+ return Promise.reject(Error('Either dcqlPayload or definitionPayload must be suppplied'))
245
+ }
246
+
247
+ let definitionId: string
248
+ if (definitionPair.dcqlPayload) {
249
+ DcqlQuery.validate(definitionPair.dcqlPayload.dcqlQuery)
250
+ console.log(`persisting DCQL definition ${definitionPair.dcqlPayload.queryId} with versionControlMode ${versionControlMode}`)
251
+ definitionId = definitionPair.dcqlPayload.queryId
252
+ }
253
+ if (definitionPayload) {
254
+ await context.agent.pexValidateDefinition({ definition: definitionPayload })
255
+ console.log(`persisting PEX definition ${definitionPayload.id} / ${definitionPayload.name} with versionControlMode ${versionControlMode}`)
256
+ definitionId = definitionPayload.id
257
+ }
243
258
 
244
- console.log(`persisting definition ${definitionPayload.id} / ${definitionPayload.name} with versionControlMode ${versionControlMode}`)
245
259
  return context.agent.pdmPersistDefinition({
246
260
  definitionItem: {
261
+ definitionId: definitionId!,
247
262
  tenantId: tenantId,
248
263
  version: version,
249
264
  definitionPayload,
@@ -256,7 +271,7 @@ export class SIOPv2RP implements IAgentPlugin {
256
271
  }
257
272
 
258
273
  private async siopGetRedirectURI(args: IGetRedirectUriArgs, context: IRequiredContext): Promise<string | undefined> {
259
- const instanceId = args.definitionId ?? SIOPv2RP._DEFAULT_OPTS_KEY
274
+ const instanceId = args.queryId ?? SIOPv2RP._DEFAULT_OPTS_KEY
260
275
  if (this.instances.has(instanceId)) {
261
276
  const rpInstance = this.instances.get(instanceId)
262
277
  if (rpInstance !== undefined) {
@@ -271,17 +286,17 @@ export class SIOPv2RP implements IAgentPlugin {
271
286
  return undefined
272
287
  }
273
288
 
274
- async getRPInstance({ definitionId, responseRedirectURI }: ISiopRPInstanceArgs, context: IRequiredContext): Promise<RPInstance> {
275
- const instanceId = definitionId ?? SIOPv2RP._DEFAULT_OPTS_KEY
289
+ async getRPInstance({ queryId, responseRedirectURI }: ISiopRPInstanceArgs, context: IRequiredContext): Promise<RPInstance> {
290
+ const instanceId = queryId ?? SIOPv2RP._DEFAULT_OPTS_KEY
276
291
  if (!this.instances.has(instanceId)) {
277
- const instanceOpts = this.getInstanceOpts(definitionId)
278
- const rpOpts = await this.getRPOptions(context, { definitionId, responseRedirectURI: responseRedirectURI })
292
+ const instanceOpts = this.getInstanceOpts(queryId)
293
+ const rpOpts = await this.getRPOptions(context, { queryId, responseRedirectURI: responseRedirectURI })
279
294
  if (!rpOpts.identifierOpts.resolveOpts?.resolver || typeof rpOpts.identifierOpts.resolveOpts.resolver.resolve !== 'function') {
280
295
  if (!rpOpts.identifierOpts?.resolveOpts) {
281
296
  rpOpts.identifierOpts = { ...rpOpts.identifierOpts }
282
297
  rpOpts.identifierOpts.resolveOpts = { ...rpOpts.identifierOpts.resolveOpts }
283
298
  }
284
- console.log('Using agent DID resolver for RP instance with definition id ' + definitionId)
299
+ console.log('Using agent DID resolver for RP instance with definition id ' + queryId)
285
300
  rpOpts.identifierOpts.resolveOpts.resolver = getAgentResolver(context, {
286
301
  uniresolverResolution: true,
287
302
  localResolution: true,
@@ -297,11 +312,11 @@ export class SIOPv2RP implements IAgentPlugin {
297
312
  return rpInstance
298
313
  }
299
314
 
300
- async getRPOptions(context: IRequiredContext, opts: { definitionId?: string; responseRedirectURI?: string }): Promise<IRPOptions> {
301
- const { definitionId, responseRedirectURI: responseRedirectURI } = opts
302
- const options = this.getInstanceOpts(definitionId)?.rpOpts ?? this.opts.defaultOpts
315
+ async getRPOptions(context: IRequiredContext, opts: { queryId?: string; responseRedirectURI?: string }): Promise<IRPOptions> {
316
+ const { queryId, responseRedirectURI: responseRedirectURI } = opts
317
+ const options = this.getInstanceOpts(queryId)?.rpOpts ?? this.opts.defaultOpts
303
318
  if (!options) {
304
- throw Error(`Could not get specific nor default options for definition ${definitionId}`)
319
+ throw Error(`Could not get specific nor default options for definition ${queryId}`)
305
320
  }
306
321
  if (this.opts.defaultOpts) {
307
322
  if (!options.identifierOpts) {
@@ -335,7 +350,7 @@ export class SIOPv2RP implements IAgentPlugin {
335
350
  getInstanceOpts(definitionId?: string): IPEXInstanceOptions | undefined {
336
351
  if (!this.opts.instanceOpts) return undefined
337
352
 
338
- const instanceOpt = definitionId ? this.opts.instanceOpts.find((i) => i.definitionId === definitionId) : undefined
353
+ const instanceOpt = definitionId ? this.opts.instanceOpts.find((i) => i.queryId === definitionId) : undefined
339
354
 
340
355
  return instanceOpt ?? this.getDefaultOptions(definitionId)
341
356
  }
@@ -343,11 +358,11 @@ export class SIOPv2RP implements IAgentPlugin {
343
358
  private getDefaultOptions(definitionId: string | undefined) {
344
359
  if (!this.opts.instanceOpts) return undefined
345
360
 
346
- const defaultOptions = this.opts.instanceOpts.find((i) => i.definitionId === 'default')
361
+ const defaultOptions = this.opts.instanceOpts.find((i) => i.queryId === 'default')
347
362
  if (defaultOptions) {
348
363
  const clonedOptions = { ...defaultOptions }
349
364
  if (definitionId !== undefined) {
350
- clonedOptions.definitionId = definitionId
365
+ clonedOptions.queryId = definitionId
351
366
  }
352
367
  return clonedOptions
353
368
  }
package/src/functions.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import {
2
- ClientIdScheme,
3
2
  ClientMetadataOpts,
4
3
  InMemoryRPSessionManager,
5
4
  PassBy,
@@ -28,7 +27,12 @@ import {
28
27
  } from '@sphereon/ssi-sdk-ext.identifier-resolution'
29
28
  import { JwtCompactResult } from '@sphereon/ssi-sdk-ext.jwt-service'
30
29
  import { IVerifySdJwtPresentationResult } from '@sphereon/ssi-sdk.sd-jwt'
31
- import { CredentialMapper, Hasher, OriginalVerifiableCredential, PresentationSubmission } from '@sphereon/ssi-types'
30
+ import {
31
+ CredentialMapper,
32
+ HasherSync,
33
+ OriginalVerifiableCredential,
34
+ PresentationSubmission
35
+ } from '@sphereon/ssi-types'
32
36
  import { IVerifyCallbackArgs, IVerifyCredentialResult, VerifyCallback } from '@sphereon/wellknown-dids-client'
33
37
  // import { KeyAlgo, SuppliedSigner } from '@sphereon/ssi-sdk.core'
34
38
  import { TKeyType } from '@veramo/core'
@@ -68,8 +72,7 @@ export function getPresentationVerificationCallback(
68
72
  ): Promise<PresentationVerificationResult> {
69
73
  if (CredentialMapper.isSdJwtEncoded(args)) {
70
74
  const result: IVerifySdJwtPresentationResult = await context.agent.verifySdJwtPresentation({
71
- presentation: args,
72
- kb: true,
75
+ presentation: args
73
76
  })
74
77
  // fixme: investigate the correct way to handle this
75
78
  return { verified: !!result.payload }
@@ -113,11 +116,11 @@ export async function createRPBuilder(args: {
113
116
  let definition: IPresentationDefinition | undefined = args.definition
114
117
  let dcqlQuery: DcqlQuery | undefined = args.dcql
115
118
 
116
- if (!definition && pexOpts && pexOpts.definitionId) {
119
+ if (!definition && pexOpts && pexOpts.queryId) {
117
120
  const presentationDefinitionItems = await context.agent.pdmGetDefinitions({
118
121
  filter: [
119
122
  {
120
- definitionId: pexOpts.definitionId,
123
+ definitionId: pexOpts.queryId,
121
124
  version: pexOpts.version,
122
125
  tenantId: pexOpts.tenantId,
123
126
  },
@@ -126,9 +129,8 @@ export async function createRPBuilder(args: {
126
129
 
127
130
  if (presentationDefinitionItems.length > 0) {
128
131
  const presentationDefinitionItem = presentationDefinitionItems[0]
129
- definition = presentationDefinitionItem.definitionPayload
130
132
  if (!dcqlQuery && presentationDefinitionItem.dcqlPayload) {
131
- dcqlQuery = presentationDefinitionItem.dcqlPayload as DcqlQuery // cast from DcqlQueryREST back to valibot DcqlQuery
133
+ dcqlQuery = presentationDefinitionItem.dcqlPayload.dcqlQuery as DcqlQuery // cast from DcqlQueryREST back to valibot DcqlQuery
132
134
  }
133
135
  }
134
136
  }
@@ -161,7 +163,7 @@ export async function createRPBuilder(args: {
161
163
  uniresolverResolution: rpOpts.identifierOpts.resolveOpts?.noUniversalResolverFallback !== true,
162
164
  })
163
165
  //todo: probably wise to first look and see if we actually need the hasher to begin with
164
- let hasher: Hasher | undefined = rpOpts.credentialOpts?.hasher
166
+ let hasher: HasherSync | undefined = rpOpts.credentialOpts?.hasher
165
167
  if (!rpOpts.credentialOpts?.hasher || typeof rpOpts.credentialOpts?.hasher !== 'function') {
166
168
  hasher = defaultHasher
167
169
  }
@@ -197,7 +199,7 @@ export async function createRPBuilder(args: {
197
199
 
198
200
  const oidfOpts = identifierOpts.oidfOpts
199
201
  if (oidfOpts && isExternalIdentifierOIDFEntityIdOpts(oidfOpts)) {
200
- builder.withEntityId(oidfOpts.identifier, PropertyTarget.REQUEST_OBJECT).withClientIdScheme('entity_id', PropertyTarget.REQUEST_OBJECT)
202
+ builder.withEntityId(oidfOpts.identifier, PropertyTarget.REQUEST_OBJECT)
201
203
  } else {
202
204
  const resolution = await context.agent.identifierManagedGet(identifierOpts.idOpts)
203
205
  builder
@@ -205,10 +207,6 @@ export async function createRPBuilder(args: {
205
207
  resolution.issuer ?? (isManagedIdentifierDidResult(resolution) ? resolution.did : resolution.jwkThumbprint),
206
208
  PropertyTarget.REQUEST_OBJECT,
207
209
  )
208
- .withClientIdScheme(
209
- (resolution.clientIdScheme as ClientIdScheme) ?? (identifierOpts.idOpts.clientIdScheme as ClientIdScheme),
210
- PropertyTarget.REQUEST_OBJECT,
211
- )
212
210
  }
213
211
 
214
212
  if (hasher) {
@@ -222,9 +220,6 @@ export async function createRPBuilder(args: {
222
220
  //fixme: this has been removed in the new version of did-auth-siop
223
221
  // builder.withWellknownDIDVerifyCallback(getWellKnownDIDVerifyCallback(didOpts, context))
224
222
 
225
- if (definition) {
226
- builder.withPresentationDefinition({ definition }, PropertyTarget.REQUEST_OBJECT)
227
- }
228
223
  if (dcqlQuery) {
229
224
  builder.withDcqlQuery(dcqlQuery)
230
225
  }
@@ -27,7 +27,7 @@ import { IPDManager, VersionControlMode } from '@sphereon/ssi-sdk.pd-manager'
27
27
  import { IPresentationExchange } from '@sphereon/ssi-sdk.presentation-exchange'
28
28
  import { ISDJwtPlugin } from '@sphereon/ssi-sdk.sd-jwt'
29
29
  import { AuthorizationRequestStateStatus } from '@sphereon/ssi-sdk.siopv2-oid4vp-common'
30
- import { AdditionalClaims, DcqlQueryREST, HasherSync } from '@sphereon/ssi-types'
30
+ import { AdditionalClaims, DcqlQueryPayload, HasherSync } from '@sphereon/ssi-types'
31
31
  import { VerifyCallback } from '@sphereon/wellknown-dids-client'
32
32
  import { IAgentContext, ICredentialIssuer, ICredentialVerifier, IDIDManager, IKeyManager, IPluginMethodMap, IResolver } from '@veramo/core'
33
33
 
@@ -52,7 +52,6 @@ export interface ISIOPv2RP extends IPluginMethodMap {
52
52
  siopDeleteAuthState(args: IDeleteAuthStateArgs, context: IRequiredContext): Promise<boolean>
53
53
  siopVerifyAuthResponse(args: IVerifyAuthResponseStateArgs, context: IRequiredContext): Promise<VerifiedAuthorizationResponse>
54
54
  siopImportDefinitions(args: ImportDefinitionsArgs, context: IRequiredContext): Promise<void>
55
-
56
55
  siopGetRedirectURI(args: IGetRedirectUriArgs, context: IRequiredContext): Promise<string | undefined>
57
56
  }
58
57
 
@@ -64,8 +63,9 @@ export interface ISiopv2RPOpts {
64
63
  export interface IRPDefaultOpts extends IRPOptions {}
65
64
 
66
65
  export interface ICreateAuthRequestArgs {
67
- definitionId: string
66
+ queryId: string
68
67
  correlationId: string
68
+ useQueryIdInstance?: boolean
69
69
  responseURIType: ResponseURIType
70
70
  responseURI: string
71
71
  responseRedirectURI?: string
@@ -78,20 +78,20 @@ export interface ICreateAuthRequestArgs {
78
78
 
79
79
  export interface IGetAuthRequestStateArgs {
80
80
  correlationId: string
81
- definitionId: string
81
+ queryId?: string
82
82
  errorOnNotFound?: boolean
83
83
  }
84
84
 
85
85
  export interface IGetAuthResponseStateArgs {
86
86
  correlationId: string
87
- definitionId: string
87
+ queryId?: string
88
88
  errorOnNotFound?: boolean
89
89
  progressRequestStateTo?: AuthorizationRequestStateStatus
90
90
  includeVerifiedData?: VerifiedDataMode
91
91
  }
92
92
 
93
93
  export interface IUpdateRequestStateArgs {
94
- definitionId: string
94
+ queryId: string
95
95
  correlationId: string
96
96
  state: AuthorizationRequestStateStatus
97
97
  error?: string
@@ -99,24 +99,24 @@ export interface IUpdateRequestStateArgs {
99
99
 
100
100
  export interface IDeleteAuthStateArgs {
101
101
  correlationId: string
102
- definitionId: string
102
+ queryId?: string
103
103
  }
104
104
 
105
105
  export interface IVerifyAuthResponseStateArgs {
106
106
  authorizationResponse: string | AuthorizationResponsePayload
107
- definitionId?: string
107
+ queryId?: string
108
108
  correlationId: string
109
109
  audience?: string
110
- dcqlQuery?: DcqlQueryREST
110
+ dcqlQueryPayload?: DcqlQueryPayload
111
111
  }
112
112
 
113
113
  export interface IDefinitionPair {
114
- definitionPayload: IPresentationDefinition
115
- dcqlPayload?: DcqlQueryREST
114
+ definitionPayload?: IPresentationDefinition
115
+ dcqlPayload?: DcqlQueryPayload
116
116
  }
117
117
 
118
118
  export interface ImportDefinitionsArgs {
119
- definitions: Array<IDefinitionPair>
119
+ queries: Array<IDefinitionPair>
120
120
  tenantId?: string
121
121
  version?: string
122
122
  versionControlMode?: VersionControlMode
@@ -124,7 +124,7 @@ export interface ImportDefinitionsArgs {
124
124
 
125
125
  export interface IGetRedirectUriArgs {
126
126
  correlationId: string
127
- definitionId?: string
127
+ queryId?: string
128
128
  state?: string
129
129
  }
130
130
 
@@ -140,7 +140,7 @@ export interface IPEXDefinitionPersistArgs extends IPEXInstanceOptions {
140
140
  }
141
141
 
142
142
  export interface ISiopRPInstanceArgs {
143
- definitionId?: string
143
+ queryId?: string
144
144
  responseRedirectURI?: string
145
145
  }
146
146
 
@@ -165,7 +165,7 @@ export interface IRPOptions {
165
165
  export interface IPEXOptions {
166
166
  presentationVerifyCallback?: PresentationVerificationCallback
167
167
  // definition?: IPresentationDefinition
168
- definitionId: string
168
+ queryId: string
169
169
  version?: string
170
170
  tenantId?: string
171
171
  }