@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth 0.34.1-feature.SSISDK.58.host.nonce.endpoint.145 → 0.34.1-feature.SSISDK.62.218
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.
- package/dist/index.cjs +417 -403
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +729 -45
- package/dist/index.d.ts +729 -45
- package/dist/index.js +410 -397
- package/dist/index.js.map +1 -1
- package/package.json +17 -17
- package/src/RPInstance.ts +11 -28
- package/src/agent/SIOPv2RP.ts +81 -58
- package/src/functions.ts +49 -46
- package/src/index.ts +1 -1
- package/src/types/ISIOPv2RP.ts +22 -33
package/src/agent/SIOPv2RP.ts
CHANGED
|
@@ -3,10 +3,15 @@ import {
|
|
|
3
3
|
AuthorizationResponsePayload,
|
|
4
4
|
AuthorizationResponseState,
|
|
5
5
|
AuthorizationResponseStateStatus,
|
|
6
|
+
AuthorizationResponseStateWithVerifiedData,
|
|
6
7
|
decodeUriAsJson,
|
|
7
|
-
VerifiedAuthorizationResponse
|
|
8
|
+
VerifiedAuthorizationResponse
|
|
8
9
|
} from '@sphereon/did-auth-siop'
|
|
9
10
|
import { getAgentResolver } from '@sphereon/ssi-sdk-ext.did-utils'
|
|
11
|
+
import { shaHasher as defaultHasher } from '@sphereon/ssi-sdk.core'
|
|
12
|
+
import { validate as isValidUUID } from 'uuid'
|
|
13
|
+
|
|
14
|
+
import type { ImportDcqlQueryItem } from '@sphereon/ssi-sdk.pd-manager'
|
|
10
15
|
import {
|
|
11
16
|
AdditionalClaims,
|
|
12
17
|
CredentialMapper,
|
|
@@ -24,7 +29,6 @@ import {
|
|
|
24
29
|
import { IAgentPlugin } from '@veramo/core'
|
|
25
30
|
import { DcqlQuery } from 'dcql'
|
|
26
31
|
import {
|
|
27
|
-
AuthorizationResponseStateWithVerifiedData,
|
|
28
32
|
IAuthorizationRequestPayloads,
|
|
29
33
|
ICreateAuthRequestArgs,
|
|
30
34
|
IGetAuthRequestStateArgs,
|
|
@@ -43,9 +47,7 @@ import {
|
|
|
43
47
|
VerifiedDataMode,
|
|
44
48
|
} from '../index'
|
|
45
49
|
import { RPInstance } from '../RPInstance'
|
|
46
|
-
|
|
47
50
|
import { ISIOPv2RP } from '../types/ISIOPv2RP'
|
|
48
|
-
import { shaHasher as defaultHasher } from '@sphereon/ssi-sdk.core'
|
|
49
51
|
|
|
50
52
|
export class SIOPv2RP implements IAgentPlugin {
|
|
51
53
|
private readonly opts: ISiopv2RPOpts
|
|
@@ -85,7 +87,14 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
private async createAuthorizationRequestURI(createArgs: ICreateAuthRequestArgs, context: IRequiredContext): Promise<string> {
|
|
88
|
-
return await this.getRPInstance(
|
|
90
|
+
return await this.getRPInstance(
|
|
91
|
+
{
|
|
92
|
+
createWhenNotPresent: true,
|
|
93
|
+
responseRedirectURI: createArgs.responseRedirectURI,
|
|
94
|
+
...(createArgs.useQueryIdInstance === true && { queryId: createArgs.queryId } ),
|
|
95
|
+
},
|
|
96
|
+
context,
|
|
97
|
+
)
|
|
89
98
|
.then((rp) => rp.createAuthorizationRequestURI(createArgs, context))
|
|
90
99
|
.then((URI) => URI.encodedUri)
|
|
91
100
|
}
|
|
@@ -94,21 +103,23 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
94
103
|
createArgs: ICreateAuthRequestArgs,
|
|
95
104
|
context: IRequiredContext,
|
|
96
105
|
): Promise<IAuthorizationRequestPayloads> {
|
|
97
|
-
return await this.getRPInstance({
|
|
106
|
+
return await this.getRPInstance({ createWhenNotPresent: true, queryId: createArgs.queryId }, context)
|
|
98
107
|
.then((rp) => rp.createAuthorizationRequest(createArgs, context))
|
|
99
108
|
.then(async (request) => {
|
|
100
109
|
const authRequest: IAuthorizationRequestPayloads = {
|
|
101
110
|
authorizationRequest: request.payload,
|
|
102
111
|
requestObject: await request.requestObjectJwt(),
|
|
103
|
-
requestObjectDecoded:
|
|
112
|
+
requestObjectDecoded: request.requestObject?.getPayload(),
|
|
104
113
|
}
|
|
105
114
|
return authRequest
|
|
106
115
|
})
|
|
107
116
|
}
|
|
108
117
|
|
|
109
118
|
private async siopGetRequestState(args: IGetAuthRequestStateArgs, context: IRequiredContext): Promise<AuthorizationRequestState | undefined> {
|
|
110
|
-
return await this.getRPInstance({
|
|
111
|
-
rp.get(context).then((rp) =>
|
|
119
|
+
return await this.getRPInstance({ createWhenNotPresent: false, queryId: args.queryId }, context).then((rp) =>
|
|
120
|
+
rp.get(context).then((rp) =>
|
|
121
|
+
rp.sessionManager.getRequestStateByCorrelationId(args.correlationId, args.errorOnNotFound)
|
|
122
|
+
),
|
|
112
123
|
)
|
|
113
124
|
}
|
|
114
125
|
|
|
@@ -116,7 +127,7 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
116
127
|
args: IGetAuthResponseStateArgs,
|
|
117
128
|
context: IRequiredContext,
|
|
118
129
|
): Promise<AuthorizationResponseStateWithVerifiedData | undefined> {
|
|
119
|
-
const rpInstance: RPInstance = await this.getRPInstance({
|
|
130
|
+
const rpInstance: RPInstance = await this.getRPInstance({ createWhenNotPresent: false, queryId: args.queryId }, context)
|
|
120
131
|
const authorizationResponseState: AuthorizationResponseState | undefined = await rpInstance
|
|
121
132
|
.get(context)
|
|
122
133
|
.then((rp) => rp.sessionManager.getResponseStateByCorrelationId(args.correlationId, args.errorOnNotFound))
|
|
@@ -193,10 +204,10 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
193
204
|
: CredentialMapper.toUniformPresentation(presentationDecoded as OriginalVerifiablePresentation)
|
|
194
205
|
|
|
195
206
|
private async siopUpdateRequestState(args: IUpdateRequestStateArgs, context: IRequiredContext): Promise<AuthorizationRequestState> {
|
|
196
|
-
if (args.state !== '
|
|
197
|
-
throw Error(`Only '
|
|
207
|
+
if (args.state !== 'authorization_request_created') {
|
|
208
|
+
throw Error(`Only 'authorization_request_created' status is supported for this method at this point`)
|
|
198
209
|
}
|
|
199
|
-
return await this.getRPInstance({
|
|
210
|
+
return await this.getRPInstance({ createWhenNotPresent: false, queryId: args.queryId }, context)
|
|
200
211
|
// todo: In the SIOP library we need to update the signal method to be more like this method
|
|
201
212
|
.then((rp) =>
|
|
202
213
|
rp.get(context).then(async (rp) => {
|
|
@@ -210,7 +221,7 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
210
221
|
}
|
|
211
222
|
|
|
212
223
|
private async siopDeleteState(args: IGetAuthResponseStateArgs, context: IRequiredContext): Promise<boolean> {
|
|
213
|
-
return await this.getRPInstance({
|
|
224
|
+
return await this.getRPInstance({ createWhenNotPresent: false, queryId: args.queryId }, context)
|
|
214
225
|
.then((rp) => rp.get(context).then((rp) => rp.sessionManager.deleteStateForCorrelationId(args.correlationId)))
|
|
215
226
|
.then(() => true)
|
|
216
227
|
}
|
|
@@ -223,45 +234,30 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
223
234
|
typeof args.authorizationResponse === 'string'
|
|
224
235
|
? (decodeUriAsJson(args.authorizationResponse) as AuthorizationResponsePayload)
|
|
225
236
|
: args.authorizationResponse
|
|
226
|
-
return await this.getRPInstance({
|
|
237
|
+
return await this.getRPInstance({ createWhenNotPresent: false, queryId: args.queryId }, context).then((rp) =>
|
|
227
238
|
rp.get(context).then((rp) =>
|
|
228
239
|
rp.verifyAuthorizationResponse(authResponse, {
|
|
229
240
|
correlationId: args.correlationId,
|
|
230
|
-
|
|
231
|
-
|
|
241
|
+
...(args.dcqlQuery ? { dcqlQuery: args.dcqlQuery } : {}),
|
|
242
|
+
audience: args.audience,
|
|
232
243
|
}),
|
|
233
244
|
),
|
|
234
245
|
)
|
|
235
246
|
}
|
|
236
247
|
|
|
237
248
|
private async siopImportDefinitions(args: ImportDefinitionsArgs, context: IRequiredContext): Promise<void> {
|
|
238
|
-
const {
|
|
249
|
+
const { importItems, tenantId, version, versionControlMode } = args
|
|
239
250
|
await Promise.all(
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
return Promise.reject(Error('Either dcqlPayload or definitionPayload must be suppplied'))
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
let definitionId: string
|
|
247
|
-
if (definitionPair.dcqlPayload) {
|
|
248
|
-
DcqlQuery.validate(definitionPair.dcqlPayload.dcqlQuery)
|
|
249
|
-
console.log(`persisting DCQL definition ${definitionPair.dcqlPayload.queryId} with versionControlMode ${versionControlMode}`)
|
|
250
|
-
definitionId = definitionPair.dcqlPayload.queryId
|
|
251
|
-
}
|
|
252
|
-
if (definitionPayload) {
|
|
253
|
-
await context.agent.pexValidateDefinition({ definition: definitionPayload })
|
|
254
|
-
console.log(`persisting PEX definition ${definitionPayload.id} / ${definitionPayload.name} with versionControlMode ${versionControlMode}`)
|
|
255
|
-
definitionId = definitionPayload.id
|
|
256
|
-
}
|
|
251
|
+
importItems.map(async (importItem: ImportDcqlQueryItem) => {
|
|
252
|
+
DcqlQuery.validate(importItem.query)
|
|
253
|
+
console.log(`persisting DCQL definition ${importItem.queryId} with versionControlMode ${versionControlMode}`)
|
|
257
254
|
|
|
258
255
|
return context.agent.pdmPersistDefinition({
|
|
259
256
|
definitionItem: {
|
|
260
|
-
|
|
257
|
+
queryId: importItem.queryId!,
|
|
261
258
|
tenantId: tenantId,
|
|
262
259
|
version: version,
|
|
263
|
-
|
|
264
|
-
dcqlPayload: definitionPair.dcqlPayload,
|
|
260
|
+
query: importItem.query,
|
|
265
261
|
},
|
|
266
262
|
opts: { versionControlMode: versionControlMode },
|
|
267
263
|
})
|
|
@@ -270,7 +266,7 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
270
266
|
}
|
|
271
267
|
|
|
272
268
|
private async siopGetRedirectURI(args: IGetRedirectUriArgs, context: IRequiredContext): Promise<string | undefined> {
|
|
273
|
-
const instanceId = args.
|
|
269
|
+
const instanceId = args.queryId ?? SIOPv2RP._DEFAULT_OPTS_KEY
|
|
274
270
|
if (this.instances.has(instanceId)) {
|
|
275
271
|
const rpInstance = this.instances.get(instanceId)
|
|
276
272
|
if (rpInstance !== undefined) {
|
|
@@ -285,37 +281,64 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
285
281
|
return undefined
|
|
286
282
|
}
|
|
287
283
|
|
|
288
|
-
async getRPInstance({
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
284
|
+
async getRPInstance({ createWhenNotPresent, queryId, responseRedirectURI }: ISiopRPInstanceArgs, context: IRequiredContext): Promise<RPInstance> {
|
|
285
|
+
let rpInstanceId: string = SIOPv2RP._DEFAULT_OPTS_KEY
|
|
286
|
+
let rpInstance: RPInstance | undefined
|
|
287
|
+
if (queryId) {
|
|
288
|
+
if (this.instances.has(queryId)) {
|
|
289
|
+
rpInstanceId = queryId
|
|
290
|
+
rpInstance = this.instances.get(rpInstanceId)!
|
|
291
|
+
} else if (isValidUUID(queryId)) {
|
|
292
|
+
try {
|
|
293
|
+
// Check whether queryId is actually the PD item id
|
|
294
|
+
const pd = await context.agent.pdmGetDefinition({ itemId: queryId })
|
|
295
|
+
if (this.instances.has(pd.queryId)) {
|
|
296
|
+
rpInstanceId = pd.queryId
|
|
297
|
+
rpInstance = this.instances.get(rpInstanceId)!
|
|
298
|
+
}
|
|
299
|
+
} catch (ignore) {}
|
|
300
|
+
}
|
|
301
|
+
if (createWhenNotPresent) {
|
|
302
|
+
rpInstanceId = queryId
|
|
303
|
+
} else {
|
|
304
|
+
rpInstance = this.instances.get(rpInstanceId)
|
|
305
|
+
}
|
|
306
|
+
} else {
|
|
307
|
+
rpInstance = this.instances.get(rpInstanceId)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (!rpInstance) {
|
|
311
|
+
if (!createWhenNotPresent) {
|
|
312
|
+
return Promise.reject(`No RP instance found for key ${rpInstanceId}`)
|
|
313
|
+
}
|
|
314
|
+
const instanceOpts = this.getInstanceOpts(queryId)
|
|
315
|
+
const rpOpts = await this.getRPOptions(context, { queryId, responseRedirectURI: responseRedirectURI })
|
|
293
316
|
if (!rpOpts.identifierOpts.resolveOpts?.resolver || typeof rpOpts.identifierOpts.resolveOpts.resolver.resolve !== 'function') {
|
|
294
317
|
if (!rpOpts.identifierOpts?.resolveOpts) {
|
|
295
318
|
rpOpts.identifierOpts = { ...rpOpts.identifierOpts }
|
|
296
319
|
rpOpts.identifierOpts.resolveOpts = { ...rpOpts.identifierOpts.resolveOpts }
|
|
297
320
|
}
|
|
298
|
-
console.log('Using agent DID resolver for RP instance with definition id ' +
|
|
321
|
+
console.log('Using agent DID resolver for RP instance with definition id ' + queryId)
|
|
299
322
|
rpOpts.identifierOpts.resolveOpts.resolver = getAgentResolver(context, {
|
|
300
323
|
uniresolverResolution: true,
|
|
301
324
|
localResolution: true,
|
|
302
325
|
resolverResolution: true,
|
|
303
326
|
})
|
|
304
327
|
}
|
|
305
|
-
|
|
328
|
+
rpInstance = new RPInstance({ rpOpts, pexOpts: instanceOpts })
|
|
329
|
+
this.instances.set(rpInstanceId, rpInstance)
|
|
306
330
|
}
|
|
307
|
-
const rpInstance = this.instances.get(instanceId)!
|
|
308
331
|
if (responseRedirectURI) {
|
|
309
332
|
rpInstance.rpOptions.responseRedirectUri = responseRedirectURI
|
|
310
333
|
}
|
|
311
334
|
return rpInstance
|
|
312
335
|
}
|
|
313
336
|
|
|
314
|
-
async getRPOptions(context: IRequiredContext, opts: {
|
|
315
|
-
const {
|
|
316
|
-
const options = this.getInstanceOpts(
|
|
337
|
+
async getRPOptions(context: IRequiredContext, opts: { queryId?: string; responseRedirectURI?: string }): Promise<IRPOptions> {
|
|
338
|
+
const { queryId, responseRedirectURI: responseRedirectURI } = opts
|
|
339
|
+
const options = this.getInstanceOpts(queryId)?.rpOpts ?? this.opts.defaultOpts
|
|
317
340
|
if (!options) {
|
|
318
|
-
throw Error(`Could not get specific nor default options for definition ${
|
|
341
|
+
throw Error(`Could not get specific nor default options for definition ${queryId}`)
|
|
319
342
|
}
|
|
320
343
|
if (this.opts.defaultOpts) {
|
|
321
344
|
if (!options.identifierOpts) {
|
|
@@ -346,22 +369,22 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
346
369
|
return options
|
|
347
370
|
}
|
|
348
371
|
|
|
349
|
-
getInstanceOpts(
|
|
372
|
+
getInstanceOpts(queryId?: string): IPEXInstanceOptions | undefined {
|
|
350
373
|
if (!this.opts.instanceOpts) return undefined
|
|
351
374
|
|
|
352
|
-
const instanceOpt =
|
|
375
|
+
const instanceOpt = queryId ? this.opts.instanceOpts.find((i) => i.queryId === queryId) : undefined
|
|
353
376
|
|
|
354
|
-
return instanceOpt ?? this.getDefaultOptions(
|
|
377
|
+
return instanceOpt ?? this.getDefaultOptions(queryId)
|
|
355
378
|
}
|
|
356
379
|
|
|
357
|
-
private getDefaultOptions(
|
|
380
|
+
private getDefaultOptions(queryId: string | undefined) {
|
|
358
381
|
if (!this.opts.instanceOpts) return undefined
|
|
359
382
|
|
|
360
|
-
const defaultOptions = this.opts.instanceOpts.find((i) => i.
|
|
383
|
+
const defaultOptions = this.opts.instanceOpts.find((i) => i.queryId === 'default')
|
|
361
384
|
if (defaultOptions) {
|
|
362
385
|
const clonedOptions = { ...defaultOptions }
|
|
363
|
-
if (
|
|
364
|
-
clonedOptions.
|
|
386
|
+
if (queryId !== undefined) {
|
|
387
|
+
clonedOptions.queryId = queryId
|
|
365
388
|
}
|
|
366
389
|
return clonedOptions
|
|
367
390
|
}
|
package/src/functions.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ClientIdentifierPrefix,
|
|
2
3
|
ClientMetadataOpts,
|
|
4
|
+
DcqlQueryLookupCallback,
|
|
3
5
|
InMemoryRPSessionManager,
|
|
4
6
|
PassBy,
|
|
5
7
|
PresentationVerificationCallback,
|
|
@@ -27,19 +29,13 @@ import {
|
|
|
27
29
|
} from '@sphereon/ssi-sdk-ext.identifier-resolution'
|
|
28
30
|
import { JwtCompactResult } from '@sphereon/ssi-sdk-ext.jwt-service'
|
|
29
31
|
import { IVerifySdJwtPresentationResult } from '@sphereon/ssi-sdk.sd-jwt'
|
|
30
|
-
import {
|
|
31
|
-
CredentialMapper,
|
|
32
|
-
HasherSync,
|
|
33
|
-
OriginalVerifiableCredential,
|
|
34
|
-
PresentationSubmission
|
|
35
|
-
} from '@sphereon/ssi-types'
|
|
32
|
+
import { CredentialMapper, HasherSync, OriginalVerifiableCredential, PresentationSubmission } from '@sphereon/ssi-types'
|
|
36
33
|
import { IVerifyCallbackArgs, IVerifyCredentialResult, VerifyCallback } from '@sphereon/wellknown-dids-client'
|
|
37
|
-
// import { KeyAlgo, SuppliedSigner } from '@sphereon/ssi-sdk.core'
|
|
38
34
|
import { TKeyType } from '@veramo/core'
|
|
39
35
|
import { JWTVerifyOptions } from 'did-jwt'
|
|
40
36
|
import { Resolvable } from 'did-resolver'
|
|
41
37
|
import { EventEmitter } from 'events'
|
|
42
|
-
import {
|
|
38
|
+
import { IRequiredContext, IRPOptions, ISIOPIdentifierOptions } from './types/ISIOPv2RP'
|
|
43
39
|
import { DcqlQuery } from 'dcql'
|
|
44
40
|
import { defaultHasher } from '@sphereon/ssi-sdk.core'
|
|
45
41
|
|
|
@@ -47,7 +43,7 @@ export function getRequestVersion(rpOptions: IRPOptions): SupportedVersion {
|
|
|
47
43
|
if (Array.isArray(rpOptions.supportedVersions) && rpOptions.supportedVersions.length > 0) {
|
|
48
44
|
return rpOptions.supportedVersions[0]
|
|
49
45
|
}
|
|
50
|
-
return SupportedVersion.
|
|
46
|
+
return SupportedVersion.OID4VP_v1
|
|
51
47
|
}
|
|
52
48
|
|
|
53
49
|
function getWellKnownDIDVerifyCallback(siopIdentifierOpts: ISIOPIdentifierOptions, context: IRequiredContext) {
|
|
@@ -62,6 +58,31 @@ function getWellKnownDIDVerifyCallback(siopIdentifierOpts: ISIOPIdentifierOption
|
|
|
62
58
|
}
|
|
63
59
|
}
|
|
64
60
|
|
|
61
|
+
export function getDcqlQueryLookupCallback(context: IRequiredContext): DcqlQueryLookupCallback {
|
|
62
|
+
async function dcqlQueryLookup(queryId: string, version?: string, tenantId?: string): Promise<DcqlQuery> {
|
|
63
|
+
// TODO Add caching?
|
|
64
|
+
const result = await context.agent.pdmGetDefinitions({
|
|
65
|
+
filter: [
|
|
66
|
+
{
|
|
67
|
+
queryId,
|
|
68
|
+
...(tenantId && { tenantId }),
|
|
69
|
+
...(version && { version }),
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: queryId,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
})
|
|
76
|
+
if (result && result.length > 0) {
|
|
77
|
+
return result[0].query
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return Promise.reject(Error(`No dcql query found for queryId ${queryId}`))
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return dcqlQueryLookup
|
|
84
|
+
}
|
|
85
|
+
|
|
65
86
|
export function getPresentationVerificationCallback(
|
|
66
87
|
idOpts: ManagedIdentifierOptsOrResult,
|
|
67
88
|
context: IRequiredContext,
|
|
@@ -72,7 +93,7 @@ export function getPresentationVerificationCallback(
|
|
|
72
93
|
): Promise<PresentationVerificationResult> {
|
|
73
94
|
if (CredentialMapper.isSdJwtEncoded(args)) {
|
|
74
95
|
const result: IVerifySdJwtPresentationResult = await context.agent.verifySdJwtPresentation({
|
|
75
|
-
presentation: args
|
|
96
|
+
presentation: args,
|
|
76
97
|
})
|
|
77
98
|
// fixme: investigate the correct way to handle this
|
|
78
99
|
return { verified: !!result.payload }
|
|
@@ -106,34 +127,11 @@ export function getPresentationVerificationCallback(
|
|
|
106
127
|
|
|
107
128
|
export async function createRPBuilder(args: {
|
|
108
129
|
rpOpts: IRPOptions
|
|
109
|
-
pexOpts?: IPEXOptions | undefined
|
|
110
130
|
definition?: IPresentationDefinition
|
|
111
|
-
dcql?: DcqlQuery
|
|
112
131
|
context: IRequiredContext
|
|
113
132
|
}): Promise<RPBuilder> {
|
|
114
|
-
const { rpOpts,
|
|
133
|
+
const { rpOpts, context } = args
|
|
115
134
|
const { identifierOpts } = rpOpts
|
|
116
|
-
let definition: IPresentationDefinition | undefined = args.definition
|
|
117
|
-
let dcqlQuery: DcqlQuery | undefined = args.dcql
|
|
118
|
-
|
|
119
|
-
if (!definition && pexOpts && pexOpts.definitionId) {
|
|
120
|
-
const presentationDefinitionItems = await context.agent.pdmGetDefinitions({
|
|
121
|
-
filter: [
|
|
122
|
-
{
|
|
123
|
-
definitionId: pexOpts.definitionId,
|
|
124
|
-
version: pexOpts.version,
|
|
125
|
-
tenantId: pexOpts.tenantId,
|
|
126
|
-
},
|
|
127
|
-
],
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
if (presentationDefinitionItems.length > 0) {
|
|
131
|
-
const presentationDefinitionItem = presentationDefinitionItems[0]
|
|
132
|
-
if (!dcqlQuery && presentationDefinitionItem.dcqlPayload) {
|
|
133
|
-
dcqlQuery = presentationDefinitionItem.dcqlPayload.dcqlQuery as DcqlQuery // cast from DcqlQueryREST back to valibot DcqlQuery
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
135
|
|
|
138
136
|
const didMethods = identifierOpts.supportedDIDMethods ?? (await getAgentDIDMethods(context))
|
|
139
137
|
const eventEmitter = rpOpts.eventEmitter ?? new EventEmitter()
|
|
@@ -173,9 +171,7 @@ export async function createRPBuilder(args: {
|
|
|
173
171
|
.withResponseMode(rpOpts.responseMode ?? ResponseMode.POST)
|
|
174
172
|
.withResponseType(ResponseType.VP_TOKEN, PropertyTarget.REQUEST_OBJECT)
|
|
175
173
|
// todo: move to options fill/correct method
|
|
176
|
-
.withSupportedVersions(
|
|
177
|
-
rpOpts.supportedVersions ?? [SupportedVersion.JWT_VC_PRESENTATION_PROFILE_v1, SupportedVersion.SIOPv2_ID1, SupportedVersion.SIOPv2_D11],
|
|
178
|
-
)
|
|
174
|
+
.withSupportedVersions(rpOpts.supportedVersions ?? [SupportedVersion.OID4VP_v1, SupportedVersion.SIOPv2_OID4VP_D28])
|
|
179
175
|
|
|
180
176
|
.withEventEmitter(eventEmitter)
|
|
181
177
|
.withSessionManager(rpOpts.sessionManager ?? new InMemoryRPSessionManager(eventEmitter))
|
|
@@ -194,6 +190,7 @@ export async function createRPBuilder(args: {
|
|
|
194
190
|
context,
|
|
195
191
|
),
|
|
196
192
|
)
|
|
193
|
+
.withDcqlQueryLookup(getDcqlQueryLookupCallback(context))
|
|
197
194
|
.withRevocationVerification(RevocationVerification.NEVER)
|
|
198
195
|
.withPresentationVerification(getPresentationVerificationCallback(identifierOpts.idOpts, context))
|
|
199
196
|
|
|
@@ -202,11 +199,12 @@ export async function createRPBuilder(args: {
|
|
|
202
199
|
builder.withEntityId(oidfOpts.identifier, PropertyTarget.REQUEST_OBJECT)
|
|
203
200
|
} else {
|
|
204
201
|
const resolution = await context.agent.identifierManagedGet(identifierOpts.idOpts)
|
|
205
|
-
|
|
206
|
-
.
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
202
|
+
const clientId: string =
|
|
203
|
+
rpOpts.clientMetadataOpts?.client_id ??
|
|
204
|
+
resolution.issuer ??
|
|
205
|
+
(isManagedIdentifierDidResult(resolution) ? resolution.did : resolution.jwkThumbprint)
|
|
206
|
+
const clientIdPrefixed = prefixClientId(clientId)
|
|
207
|
+
builder.withClientId(clientIdPrefixed, PropertyTarget.REQUEST_OBJECT)
|
|
210
208
|
}
|
|
211
209
|
|
|
212
210
|
if (hasher) {
|
|
@@ -220,10 +218,6 @@ export async function createRPBuilder(args: {
|
|
|
220
218
|
//fixme: this has been removed in the new version of did-auth-siop
|
|
221
219
|
// builder.withWellknownDIDVerifyCallback(getWellKnownDIDVerifyCallback(didOpts, context))
|
|
222
220
|
|
|
223
|
-
if (dcqlQuery) {
|
|
224
|
-
builder.withDcqlQuery(dcqlQuery)
|
|
225
|
-
}
|
|
226
|
-
|
|
227
221
|
if (rpOpts.responseRedirectUri) {
|
|
228
222
|
builder.withResponseRedirectUri(rpOpts.responseRedirectUri)
|
|
229
223
|
}
|
|
@@ -304,3 +298,12 @@ export function getSigningAlgo(type: TKeyType): SigningAlgo {
|
|
|
304
298
|
throw Error('Key type not yet supported')
|
|
305
299
|
}
|
|
306
300
|
}
|
|
301
|
+
|
|
302
|
+
export function prefixClientId(clientId: string): string {
|
|
303
|
+
// FIXME SSISDK-60
|
|
304
|
+
if (clientId.startsWith('did:')) {
|
|
305
|
+
return `${ClientIdentifierPrefix.DECENTRALIZED_IDENTIFIER}:${clientId}`
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return clientId
|
|
309
|
+
}
|
package/src/index.ts
CHANGED
package/src/types/ISIOPv2RP.ts
CHANGED
|
@@ -2,7 +2,8 @@ import {
|
|
|
2
2
|
AuthorizationRequestPayload,
|
|
3
3
|
AuthorizationRequestState,
|
|
4
4
|
AuthorizationResponsePayload,
|
|
5
|
-
|
|
5
|
+
AuthorizationResponseStateWithVerifiedData,
|
|
6
|
+
CallbackOpts,
|
|
6
7
|
ClaimPayloadCommonOpts,
|
|
7
8
|
ClientMetadataOpts,
|
|
8
9
|
IRPSessionManager,
|
|
@@ -23,14 +24,14 @@ import { ExternalIdentifierOIDFEntityIdOpts, IIdentifierResolution, ManagedIdent
|
|
|
23
24
|
import { IJwtService } from '@sphereon/ssi-sdk-ext.jwt-service'
|
|
24
25
|
import { ICredentialValidation, SchemaValidation } from '@sphereon/ssi-sdk.credential-validation'
|
|
25
26
|
import { ImDLMdoc } from '@sphereon/ssi-sdk.mdl-mdoc'
|
|
26
|
-
import { IPDManager, VersionControlMode } from '@sphereon/ssi-sdk.pd-manager'
|
|
27
|
+
import { ImportDcqlQueryItem, IPDManager, VersionControlMode } from '@sphereon/ssi-sdk.pd-manager'
|
|
27
28
|
import { IPresentationExchange } from '@sphereon/ssi-sdk.presentation-exchange'
|
|
28
29
|
import { ISDJwtPlugin } from '@sphereon/ssi-sdk.sd-jwt'
|
|
29
30
|
import { AuthorizationRequestStateStatus } from '@sphereon/ssi-sdk.siopv2-oid4vp-common'
|
|
30
|
-
import {
|
|
31
|
+
import { HasherSync } from '@sphereon/ssi-types'
|
|
31
32
|
import { VerifyCallback } from '@sphereon/wellknown-dids-client'
|
|
32
|
-
import { IAgentContext,
|
|
33
|
-
|
|
33
|
+
import { IAgentContext, ICredentialVerifier, IDIDManager, IKeyManager, IPluginMethodMap, IResolver } from '@veramo/core'
|
|
34
|
+
import { DcqlQuery } from 'dcql'
|
|
34
35
|
import { Resolvable } from 'did-resolver'
|
|
35
36
|
import { EventEmitter } from 'events'
|
|
36
37
|
|
|
@@ -52,7 +53,6 @@ export interface ISIOPv2RP extends IPluginMethodMap {
|
|
|
52
53
|
siopDeleteAuthState(args: IDeleteAuthStateArgs, context: IRequiredContext): Promise<boolean>
|
|
53
54
|
siopVerifyAuthResponse(args: IVerifyAuthResponseStateArgs, context: IRequiredContext): Promise<VerifiedAuthorizationResponse>
|
|
54
55
|
siopImportDefinitions(args: ImportDefinitionsArgs, context: IRequiredContext): Promise<void>
|
|
55
|
-
|
|
56
56
|
siopGetRedirectURI(args: IGetRedirectUriArgs, context: IRequiredContext): Promise<string | undefined>
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -64,8 +64,9 @@ export interface ISiopv2RPOpts {
|
|
|
64
64
|
export interface IRPDefaultOpts extends IRPOptions {}
|
|
65
65
|
|
|
66
66
|
export interface ICreateAuthRequestArgs {
|
|
67
|
-
|
|
67
|
+
queryId: string
|
|
68
68
|
correlationId: string
|
|
69
|
+
useQueryIdInstance?: boolean
|
|
69
70
|
responseURIType: ResponseURIType
|
|
70
71
|
responseURI: string
|
|
71
72
|
responseRedirectURI?: string
|
|
@@ -74,24 +75,25 @@ export interface ICreateAuthRequestArgs {
|
|
|
74
75
|
nonce?: string
|
|
75
76
|
state?: string
|
|
76
77
|
claims?: ClaimPayloadCommonOpts
|
|
78
|
+
callback?: CallbackOpts
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
export interface IGetAuthRequestStateArgs {
|
|
80
82
|
correlationId: string
|
|
81
|
-
|
|
83
|
+
queryId?: string
|
|
82
84
|
errorOnNotFound?: boolean
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
export interface IGetAuthResponseStateArgs {
|
|
86
88
|
correlationId: string
|
|
87
|
-
|
|
89
|
+
queryId?: string
|
|
88
90
|
errorOnNotFound?: boolean
|
|
89
91
|
progressRequestStateTo?: AuthorizationRequestStateStatus
|
|
90
92
|
includeVerifiedData?: VerifiedDataMode
|
|
91
93
|
}
|
|
92
94
|
|
|
93
95
|
export interface IUpdateRequestStateArgs {
|
|
94
|
-
|
|
96
|
+
queryId: string
|
|
95
97
|
correlationId: string
|
|
96
98
|
state: AuthorizationRequestStateStatus
|
|
97
99
|
error?: string
|
|
@@ -99,24 +101,18 @@ export interface IUpdateRequestStateArgs {
|
|
|
99
101
|
|
|
100
102
|
export interface IDeleteAuthStateArgs {
|
|
101
103
|
correlationId: string
|
|
102
|
-
|
|
104
|
+
queryId?: string
|
|
103
105
|
}
|
|
104
106
|
|
|
105
107
|
export interface IVerifyAuthResponseStateArgs {
|
|
106
108
|
authorizationResponse: string | AuthorizationResponsePayload
|
|
107
|
-
|
|
109
|
+
queryId?: string
|
|
108
110
|
correlationId: string
|
|
109
111
|
audience?: string
|
|
110
|
-
|
|
112
|
+
dcqlQuery?: DcqlQuery
|
|
111
113
|
}
|
|
112
|
-
|
|
113
|
-
export interface IDefinitionPair {
|
|
114
|
-
definitionPayload?: IPresentationDefinition
|
|
115
|
-
dcqlPayload?: DcqlQueryPayload
|
|
116
|
-
}
|
|
117
|
-
|
|
118
114
|
export interface ImportDefinitionsArgs {
|
|
119
|
-
|
|
115
|
+
importItems: Array<ImportDcqlQueryItem>
|
|
120
116
|
tenantId?: string
|
|
121
117
|
version?: string
|
|
122
118
|
versionControlMode?: VersionControlMode
|
|
@@ -124,7 +120,7 @@ export interface ImportDefinitionsArgs {
|
|
|
124
120
|
|
|
125
121
|
export interface IGetRedirectUriArgs {
|
|
126
122
|
correlationId: string
|
|
127
|
-
|
|
123
|
+
queryId?: string
|
|
128
124
|
state?: string
|
|
129
125
|
}
|
|
130
126
|
|
|
@@ -140,11 +136,12 @@ export interface IPEXDefinitionPersistArgs extends IPEXInstanceOptions {
|
|
|
140
136
|
}
|
|
141
137
|
|
|
142
138
|
export interface ISiopRPInstanceArgs {
|
|
143
|
-
|
|
139
|
+
createWhenNotPresent: boolean
|
|
140
|
+
queryId?: string
|
|
144
141
|
responseRedirectURI?: string
|
|
145
142
|
}
|
|
146
143
|
|
|
147
|
-
export interface IPEXInstanceOptions extends
|
|
144
|
+
export interface IPEXInstanceOptions extends IPresentationOptions {
|
|
148
145
|
rpOpts?: IRPOptions
|
|
149
146
|
}
|
|
150
147
|
|
|
@@ -162,12 +159,9 @@ export interface IRPOptions {
|
|
|
162
159
|
responseRedirectUri?: string
|
|
163
160
|
}
|
|
164
161
|
|
|
165
|
-
export interface
|
|
162
|
+
export interface IPresentationOptions {
|
|
163
|
+
queryId: string
|
|
166
164
|
presentationVerifyCallback?: PresentationVerificationCallback
|
|
167
|
-
// definition?: IPresentationDefinition
|
|
168
|
-
definitionId: string
|
|
169
|
-
version?: string
|
|
170
|
-
tenantId?: string
|
|
171
165
|
}
|
|
172
166
|
|
|
173
167
|
export type VerificationPolicies = {
|
|
@@ -198,16 +192,11 @@ export type CredentialOpts = {
|
|
|
198
192
|
hasher?: HasherSync
|
|
199
193
|
}
|
|
200
194
|
|
|
201
|
-
export interface AuthorizationResponseStateWithVerifiedData extends AuthorizationResponseState {
|
|
202
|
-
verifiedData?: AdditionalClaims
|
|
203
|
-
}
|
|
204
|
-
|
|
205
195
|
export type IRequiredContext = IAgentContext<
|
|
206
196
|
IResolver &
|
|
207
197
|
IDIDManager &
|
|
208
198
|
IKeyManager &
|
|
209
199
|
IIdentifierResolution &
|
|
210
|
-
ICredentialIssuer &
|
|
211
200
|
ICredentialValidation &
|
|
212
201
|
ICredentialVerifier &
|
|
213
202
|
IPresentationExchange &
|