@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth 0.34.1-feature.SSISDK.57.uni.client.169 → 0.34.1-feature.SSISDK.57.uni.client.173
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 +71 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -13
- package/dist/index.d.ts +9 -13
- package/dist/index.js +71 -47
- package/dist/index.js.map +1 -1
- package/package.json +17 -17
- package/src/RPInstance.ts +7 -26
- package/src/agent/SIOPv2RP.ts +44 -12
- package/src/functions.ts +29 -29
- package/src/types/ISIOPv2RP.ts +4 -6
package/src/agent/SIOPv2RP.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
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 { validate as isValidUUID } from 'uuid'
|
|
12
13
|
|
|
13
14
|
import type { ImportDcqlQueryItem } from '@sphereon/ssi-sdk.pd-manager'
|
|
14
15
|
import {
|
|
@@ -87,7 +88,11 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
87
88
|
|
|
88
89
|
private async createAuthorizationRequestURI(createArgs: ICreateAuthRequestArgs, context: IRequiredContext): Promise<string> {
|
|
89
90
|
return await this.getRPInstance(
|
|
90
|
-
{
|
|
91
|
+
{
|
|
92
|
+
createWhenNotPresent: true,
|
|
93
|
+
responseRedirectURI: createArgs.responseRedirectURI,
|
|
94
|
+
...(createArgs.useQueryIdInstance === true && { queryId: createArgs.queryId }),
|
|
95
|
+
},
|
|
91
96
|
context,
|
|
92
97
|
)
|
|
93
98
|
.then((rp) => rp.createAuthorizationRequestURI(createArgs, context))
|
|
@@ -98,7 +103,7 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
98
103
|
createArgs: ICreateAuthRequestArgs,
|
|
99
104
|
context: IRequiredContext,
|
|
100
105
|
): Promise<IAuthorizationRequestPayloads> {
|
|
101
|
-
return await this.getRPInstance({ queryId: createArgs.queryId }, context)
|
|
106
|
+
return await this.getRPInstance({ createWhenNotPresent: true, queryId: createArgs.queryId }, context)
|
|
102
107
|
.then((rp) => rp.createAuthorizationRequest(createArgs, context))
|
|
103
108
|
.then(async (request) => {
|
|
104
109
|
const authRequest: IAuthorizationRequestPayloads = {
|
|
@@ -111,7 +116,7 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
private async siopGetRequestState(args: IGetAuthRequestStateArgs, context: IRequiredContext): Promise<AuthorizationRequestState | undefined> {
|
|
114
|
-
return await this.getRPInstance({ queryId: args.queryId }, context).then((rp) =>
|
|
119
|
+
return await this.getRPInstance({ createWhenNotPresent: false, queryId: args.queryId }, context).then((rp) =>
|
|
115
120
|
rp.get(context).then((rp) => rp.sessionManager.getRequestStateByCorrelationId(args.correlationId, args.errorOnNotFound)),
|
|
116
121
|
)
|
|
117
122
|
}
|
|
@@ -120,7 +125,7 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
120
125
|
args: IGetAuthResponseStateArgs,
|
|
121
126
|
context: IRequiredContext,
|
|
122
127
|
): Promise<AuthorizationResponseStateWithVerifiedData | undefined> {
|
|
123
|
-
const rpInstance: RPInstance = await this.getRPInstance({ queryId: args.queryId }, context)
|
|
128
|
+
const rpInstance: RPInstance = await this.getRPInstance({ createWhenNotPresent: false, queryId: args.queryId }, context)
|
|
124
129
|
const authorizationResponseState: AuthorizationResponseState | undefined = await rpInstance
|
|
125
130
|
.get(context)
|
|
126
131
|
.then((rp) => rp.sessionManager.getResponseStateByCorrelationId(args.correlationId, args.errorOnNotFound))
|
|
@@ -200,7 +205,7 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
200
205
|
if (args.state !== 'authorization_request_created') {
|
|
201
206
|
throw Error(`Only 'authorization_request_created' status is supported for this method at this point`)
|
|
202
207
|
}
|
|
203
|
-
return await this.getRPInstance({ queryId: args.queryId }, context)
|
|
208
|
+
return await this.getRPInstance({ createWhenNotPresent: false, queryId: args.queryId }, context)
|
|
204
209
|
// todo: In the SIOP library we need to update the signal method to be more like this method
|
|
205
210
|
.then((rp) =>
|
|
206
211
|
rp.get(context).then(async (rp) => {
|
|
@@ -214,7 +219,7 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
214
219
|
}
|
|
215
220
|
|
|
216
221
|
private async siopDeleteState(args: IGetAuthResponseStateArgs, context: IRequiredContext): Promise<boolean> {
|
|
217
|
-
return await this.getRPInstance({ queryId: args.queryId }, context)
|
|
222
|
+
return await this.getRPInstance({ createWhenNotPresent: false, queryId: args.queryId }, context)
|
|
218
223
|
.then((rp) => rp.get(context).then((rp) => rp.sessionManager.deleteStateForCorrelationId(args.correlationId)))
|
|
219
224
|
.then(() => true)
|
|
220
225
|
}
|
|
@@ -227,7 +232,7 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
227
232
|
typeof args.authorizationResponse === 'string'
|
|
228
233
|
? (decodeUriAsJson(args.authorizationResponse) as AuthorizationResponsePayload)
|
|
229
234
|
: args.authorizationResponse
|
|
230
|
-
return await this.getRPInstance({ queryId: args.queryId }, context).then((rp) =>
|
|
235
|
+
return await this.getRPInstance({ createWhenNotPresent: false, queryId: args.queryId }, context).then((rp) =>
|
|
231
236
|
rp.get(context).then((rp) =>
|
|
232
237
|
rp.verifyAuthorizationResponse(authResponse, {
|
|
233
238
|
correlationId: args.correlationId,
|
|
@@ -274,9 +279,36 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
274
279
|
return undefined
|
|
275
280
|
}
|
|
276
281
|
|
|
277
|
-
async getRPInstance({ queryId, responseRedirectURI }: ISiopRPInstanceArgs, context: IRequiredContext): Promise<RPInstance> {
|
|
278
|
-
|
|
279
|
-
|
|
282
|
+
async getRPInstance({ createWhenNotPresent, queryId, responseRedirectURI }: ISiopRPInstanceArgs, context: IRequiredContext): Promise<RPInstance> {
|
|
283
|
+
let rpInstanceId: string = SIOPv2RP._DEFAULT_OPTS_KEY
|
|
284
|
+
let rpInstance: RPInstance | undefined
|
|
285
|
+
if (queryId) {
|
|
286
|
+
if (this.instances.has(queryId)) {
|
|
287
|
+
rpInstanceId = queryId
|
|
288
|
+
rpInstance = this.instances.get(rpInstanceId)!
|
|
289
|
+
} else if (isValidUUID(queryId)) {
|
|
290
|
+
try {
|
|
291
|
+
// Check whether queryId is actually the PD item id
|
|
292
|
+
const pd = await context.agent.pdmGetDefinition({ itemId: queryId })
|
|
293
|
+
if (this.instances.has(pd.queryId)) {
|
|
294
|
+
rpInstanceId = pd.queryId
|
|
295
|
+
rpInstance = this.instances.get(rpInstanceId)!
|
|
296
|
+
}
|
|
297
|
+
} catch (ignore) {}
|
|
298
|
+
}
|
|
299
|
+
if (createWhenNotPresent) {
|
|
300
|
+
rpInstanceId = queryId
|
|
301
|
+
} else {
|
|
302
|
+
rpInstance = this.instances.get(rpInstanceId)
|
|
303
|
+
}
|
|
304
|
+
} else {
|
|
305
|
+
rpInstance = this.instances.get(rpInstanceId)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (!rpInstance) {
|
|
309
|
+
if (!createWhenNotPresent) {
|
|
310
|
+
return Promise.reject(`No RP instance found for key ${rpInstanceId}`)
|
|
311
|
+
}
|
|
280
312
|
const instanceOpts = this.getInstanceOpts(queryId)
|
|
281
313
|
const rpOpts = await this.getRPOptions(context, { queryId, responseRedirectURI: responseRedirectURI })
|
|
282
314
|
if (!rpOpts.identifierOpts.resolveOpts?.resolver || typeof rpOpts.identifierOpts.resolveOpts.resolver.resolve !== 'function') {
|
|
@@ -291,9 +323,9 @@ export class SIOPv2RP implements IAgentPlugin {
|
|
|
291
323
|
resolverResolution: true,
|
|
292
324
|
})
|
|
293
325
|
}
|
|
294
|
-
|
|
326
|
+
rpInstance = new RPInstance({ rpOpts, pexOpts: instanceOpts })
|
|
327
|
+
this.instances.set(rpInstanceId, rpInstance)
|
|
295
328
|
}
|
|
296
|
-
const rpInstance = this.instances.get(instanceId)!
|
|
297
329
|
if (responseRedirectURI) {
|
|
298
330
|
rpInstance.rpOptions.responseRedirectUri = responseRedirectURI
|
|
299
331
|
}
|
package/src/functions.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ClientMetadataOpts,
|
|
3
|
+
DcqlQueryLookupCallback,
|
|
3
4
|
InMemoryRPSessionManager,
|
|
4
5
|
PassBy,
|
|
5
6
|
PresentationVerificationCallback,
|
|
@@ -34,7 +35,7 @@ import { TKeyType } from '@veramo/core'
|
|
|
34
35
|
import { JWTVerifyOptions } from 'did-jwt'
|
|
35
36
|
import { Resolvable } from 'did-resolver'
|
|
36
37
|
import { EventEmitter } from 'events'
|
|
37
|
-
import {
|
|
38
|
+
import { IRequiredContext, IRPOptions, ISIOPIdentifierOptions } from './types/ISIOPv2RP'
|
|
38
39
|
import { DcqlQuery } from 'dcql'
|
|
39
40
|
import { defaultHasher } from '@sphereon/ssi-sdk.core'
|
|
40
41
|
|
|
@@ -57,6 +58,31 @@ function getWellKnownDIDVerifyCallback(siopIdentifierOpts: ISIOPIdentifierOption
|
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
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: queryId,
|
|
68
|
+
version: version,
|
|
69
|
+
tenantId: tenantId,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: queryId,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
})
|
|
76
|
+
if (result && result.length > 0) {
|
|
77
|
+
return result[0].dcqlQuery
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return Promise.reject(Error(`No dcql query found for queryId ${queryId}`))
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return dcqlQueryLookup
|
|
84
|
+
}
|
|
85
|
+
|
|
60
86
|
export function getPresentationVerificationCallback(
|
|
61
87
|
idOpts: ManagedIdentifierOptsOrResult,
|
|
62
88
|
context: IRequiredContext,
|
|
@@ -101,34 +127,11 @@ export function getPresentationVerificationCallback(
|
|
|
101
127
|
|
|
102
128
|
export async function createRPBuilder(args: {
|
|
103
129
|
rpOpts: IRPOptions
|
|
104
|
-
pexOpts?: IPEXOptions | undefined
|
|
105
130
|
definition?: IPresentationDefinition
|
|
106
|
-
dcql?: DcqlQuery
|
|
107
131
|
context: IRequiredContext
|
|
108
132
|
}): Promise<RPBuilder> {
|
|
109
|
-
const { rpOpts,
|
|
133
|
+
const { rpOpts, context } = args
|
|
110
134
|
const { identifierOpts } = rpOpts
|
|
111
|
-
let definition: IPresentationDefinition | undefined = args.definition
|
|
112
|
-
let dcqlQuery: DcqlQuery | undefined = args.dcql
|
|
113
|
-
|
|
114
|
-
if (!definition && pexOpts && pexOpts.queryId) {
|
|
115
|
-
const presentationDefinitionItems = await context.agent.pdmGetDefinitions({
|
|
116
|
-
filter: [
|
|
117
|
-
{
|
|
118
|
-
queryId: pexOpts.queryId,
|
|
119
|
-
version: pexOpts.version,
|
|
120
|
-
tenantId: pexOpts.tenantId,
|
|
121
|
-
},
|
|
122
|
-
],
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
if (presentationDefinitionItems.length > 0) {
|
|
126
|
-
const presentationDefinitionItem = presentationDefinitionItems[0]
|
|
127
|
-
if (!dcqlQuery) {
|
|
128
|
-
dcqlQuery = presentationDefinitionItem.dcqlQuery
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
135
|
|
|
133
136
|
const didMethods = identifierOpts.supportedDIDMethods ?? (await getAgentDIDMethods(context))
|
|
134
137
|
const eventEmitter = rpOpts.eventEmitter ?? new EventEmitter()
|
|
@@ -189,6 +192,7 @@ export async function createRPBuilder(args: {
|
|
|
189
192
|
context,
|
|
190
193
|
),
|
|
191
194
|
)
|
|
195
|
+
.withDcqlQueryLookup(getDcqlQueryLookupCallback(context))
|
|
192
196
|
.withRevocationVerification(RevocationVerification.NEVER)
|
|
193
197
|
.withPresentationVerification(getPresentationVerificationCallback(identifierOpts.idOpts, context))
|
|
194
198
|
|
|
@@ -214,10 +218,6 @@ export async function createRPBuilder(args: {
|
|
|
214
218
|
//fixme: this has been removed in the new version of did-auth-siop
|
|
215
219
|
// builder.withWellknownDIDVerifyCallback(getWellKnownDIDVerifyCallback(didOpts, context))
|
|
216
220
|
|
|
217
|
-
if (dcqlQuery) {
|
|
218
|
-
builder.withDcqlQuery(dcqlQuery)
|
|
219
|
-
}
|
|
220
|
-
|
|
221
221
|
if (rpOpts.responseRedirectUri) {
|
|
222
222
|
builder.withResponseRedirectUri(rpOpts.responseRedirectUri)
|
|
223
223
|
}
|
package/src/types/ISIOPv2RP.ts
CHANGED
|
@@ -137,11 +137,12 @@ export interface IPEXDefinitionPersistArgs extends IPEXInstanceOptions {
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
export interface ISiopRPInstanceArgs {
|
|
140
|
+
createWhenNotPresent: boolean
|
|
140
141
|
queryId?: string
|
|
141
142
|
responseRedirectURI?: string
|
|
142
143
|
}
|
|
143
144
|
|
|
144
|
-
export interface IPEXInstanceOptions extends
|
|
145
|
+
export interface IPEXInstanceOptions extends IPresentationOptions {
|
|
145
146
|
rpOpts?: IRPOptions
|
|
146
147
|
}
|
|
147
148
|
|
|
@@ -159,12 +160,9 @@ export interface IRPOptions {
|
|
|
159
160
|
responseRedirectUri?: string
|
|
160
161
|
}
|
|
161
162
|
|
|
162
|
-
export interface
|
|
163
|
-
presentationVerifyCallback?: PresentationVerificationCallback
|
|
164
|
-
// definition?: IPresentationDefinition
|
|
163
|
+
export interface IPresentationOptions {
|
|
165
164
|
queryId: string
|
|
166
|
-
|
|
167
|
-
tenantId?: string
|
|
165
|
+
presentationVerifyCallback?: PresentationVerificationCallback
|
|
168
166
|
}
|
|
169
167
|
|
|
170
168
|
export type VerificationPolicies = {
|