@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.
- package/dist/index.cjs +28 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -10
- package/dist/index.d.ts +8 -10
- package/dist/index.js +28 -66
- package/dist/index.js.map +1 -1
- package/package.json +17 -17
- package/src/agent/SIOPv2RP.ts +40 -136
- package/src/functions.ts +8 -11
- package/src/types/ISIOPv2RP.ts +7 -12
package/src/agent/SIOPv2RP.ts
CHANGED
|
@@ -4,20 +4,18 @@ import {
|
|
|
4
4
|
AuthorizationResponseState,
|
|
5
5
|
AuthorizationResponseStateStatus,
|
|
6
6
|
AuthorizationResponseStateWithVerifiedData,
|
|
7
|
-
decodeUriAsJson,
|
|
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(
|
|
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 (
|
|
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
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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 {
|
|
241
|
+
const { importItems, tenantId, version, versionControlMode } = args
|
|
323
242
|
await Promise.all(
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
-
|
|
249
|
+
queryId: importItem.queryId!,
|
|
345
250
|
tenantId: tenantId,
|
|
346
251
|
version: version,
|
|
347
|
-
|
|
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
|
-
|
|
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 ??
|
|
206
|
-
|
|
207
|
-
|
|
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) {
|
package/src/types/ISIOPv2RP.ts
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
93
|
+
includeVerifiedData?: VerifiedDataMode
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
export interface IUpdateRequestStateArgs {
|
|
96
|
-
queryId
|
|
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
|
-
|
|
113
|
+
dcqlQuery?: DcqlQuery
|
|
113
114
|
}
|
|
114
|
-
|
|
115
|
-
export interface IDefinitionPair {
|
|
116
|
-
definitionPayload?: IPresentationDefinition
|
|
117
|
-
dcqlPayload?: DcqlQueryPayload
|
|
118
|
-
}
|
|
119
|
-
|
|
120
115
|
export interface ImportDefinitionsArgs {
|
|
121
|
-
|
|
116
|
+
importItems: Array<ImportDcqlQueryItem>
|
|
122
117
|
tenantId?: string
|
|
123
118
|
version?: string
|
|
124
119
|
versionControlMode?: VersionControlMode
|