@sphereon/ssi-sdk.siopv2-oid4vp-op-auth 0.34.1-feature.merge.crypto.extensions.modules.37 → 0.34.1-fix.103
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 +592 -1115
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +709 -111
- package/dist/index.d.ts +709 -111
- package/dist/index.js +518 -1041
- package/dist/index.js.map +1 -1
- package/package.json +24 -24
- package/src/agent/DidAuthSiopOpAuthenticator.ts +18 -136
- package/src/index.ts +2 -1
- package/src/machine/Siopv2Machine.ts +4 -4
- package/src/services/Siopv2MachineService.ts +97 -203
- package/src/session/OID4VP.ts +310 -299
- package/src/session/OpSession.ts +22 -114
- package/src/types/IDidAuthSiopOpAuthenticator.ts +5 -58
- package/src/types/identifier/index.ts +0 -4
- package/src/types/siop-service/index.ts +1 -3
- package/src/utils/CredentialUtils.ts +1 -39
- package/src/utils/dcql.ts +22 -19
package/src/session/OpSession.ts
CHANGED
|
@@ -2,36 +2,30 @@ import {
|
|
|
2
2
|
AuthorizationResponsePayload,
|
|
3
3
|
JwksMetadataParams,
|
|
4
4
|
OP,
|
|
5
|
-
PresentationDefinitionWithLocation,
|
|
6
|
-
PresentationExchangeResponseOpts,
|
|
7
|
-
PresentationVerificationResult,
|
|
8
5
|
RequestObjectPayload,
|
|
9
6
|
ResponseIss,
|
|
10
7
|
SupportedVersion,
|
|
11
8
|
URI,
|
|
12
9
|
Verification,
|
|
13
|
-
VerifiedAuthorizationRequest
|
|
10
|
+
VerifiedAuthorizationRequest
|
|
14
11
|
} from '@sphereon/did-auth-siop'
|
|
15
12
|
import { ResolveOpts } from '@sphereon/did-auth-siop-adapter'
|
|
16
13
|
import { JwtIssuer } from '@sphereon/oid4vc-common'
|
|
17
14
|
import { getAgentDIDMethods, getAgentResolver } from '@sphereon/ssi-sdk-ext.did-utils'
|
|
18
15
|
import { JweAlg, JweEnc } from '@sphereon/ssi-sdk-ext.jwt-service'
|
|
19
16
|
import { encodeBase64url } from '@sphereon/ssi-sdk.core'
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
CredentialMapper,
|
|
23
|
-
HasherSync,
|
|
24
|
-
OriginalVerifiableCredential,
|
|
25
|
-
parseDid,
|
|
26
|
-
PresentationSubmission,
|
|
27
|
-
W3CVerifiablePresentation,
|
|
28
|
-
} from '@sphereon/ssi-types'
|
|
29
|
-
import { IIdentifier, IVerifyResult, TKeyType } from '@veramo/core'
|
|
17
|
+
import { parseDid } from '@sphereon/ssi-types'
|
|
18
|
+
import { IIdentifier, TKeyType } from '@veramo/core'
|
|
30
19
|
import { v4 } from 'uuid'
|
|
31
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
IOPOptions,
|
|
22
|
+
IOpSessionArgs,
|
|
23
|
+
IOpSessionGetOID4VPArgs,
|
|
24
|
+
IOpsSendSiopAuthorizationResponseArgs,
|
|
25
|
+
IRequiredContext
|
|
26
|
+
} from '../types'
|
|
32
27
|
import { createOP } from './functions'
|
|
33
28
|
import { OID4VP } from './OID4VP'
|
|
34
|
-
import { PEX } from '@sphereon/pex'
|
|
35
29
|
import { Loggers } from '@sphereon/ssi-types'
|
|
36
30
|
|
|
37
31
|
const logger = Loggers.DEFAULT.get('sphereon:oid4vp:OpSession')
|
|
@@ -45,14 +39,12 @@ export class OpSession {
|
|
|
45
39
|
private verifiedAuthorizationRequest?: VerifiedAuthorizationRequest | undefined
|
|
46
40
|
private _nonce?: string
|
|
47
41
|
private _state?: string
|
|
48
|
-
private readonly _providedPresentationDefinitions?: PresentationDefinitionWithLocation[]
|
|
49
42
|
|
|
50
43
|
private constructor(options: Required<IOpSessionArgs>) {
|
|
51
44
|
this.id = options.sessionId
|
|
52
45
|
this.options = options.op
|
|
53
46
|
this.context = options.context
|
|
54
47
|
this.requestJwtOrUri = options.requestJwtOrUri
|
|
55
|
-
this._providedPresentationDefinitions = options.providedPresentationDefinitions
|
|
56
48
|
}
|
|
57
49
|
|
|
58
50
|
public static async init(options: Required<IOpSessionArgs>): Promise<OpSession> {
|
|
@@ -169,7 +161,7 @@ export class OpSession {
|
|
|
169
161
|
}
|
|
170
162
|
const isEBSI =
|
|
171
163
|
rpMethods.length === 0 &&
|
|
172
|
-
(authReq.issuer?.includes('.ebsi.eu') ||
|
|
164
|
+
(authReq.issuer?.includes('.ebsi.eu') || authReq.authorizationRequest.getMergedProperty<string>('client_id')?.includes('.ebsi.eu'))
|
|
173
165
|
let codecName: string | undefined = undefined
|
|
174
166
|
if (isEBSI && (!aud || !aud.startsWith('http'))) {
|
|
175
167
|
logger.debug(`EBSI detected, adding did:key to supported DID methods for RP`)
|
|
@@ -221,51 +213,10 @@ export class OpSession {
|
|
|
221
213
|
return Promise.resolve(this.verifiedAuthorizationRequest!.responseURI!)
|
|
222
214
|
}
|
|
223
215
|
|
|
224
|
-
public async hasPresentationDefinitions(): Promise<boolean> {
|
|
225
|
-
const defs = this._providedPresentationDefinitions ?? (await this.getAuthorizationRequest()).presentationDefinitions
|
|
226
|
-
return defs !== undefined && defs.length > 0
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
public async getPresentationDefinitions(): Promise<Array<PresentationDefinitionWithLocation> | undefined> {
|
|
230
|
-
if (!(await this.hasPresentationDefinitions())) {
|
|
231
|
-
throw Error(`No presentation definitions found`)
|
|
232
|
-
}
|
|
233
|
-
return this._providedPresentationDefinitions ?? (await this.getAuthorizationRequest()).presentationDefinitions
|
|
234
|
-
}
|
|
235
|
-
|
|
236
216
|
public async getOID4VP(args: IOpSessionGetOID4VPArgs): Promise<OID4VP> {
|
|
237
217
|
return await OID4VP.init(this, args.allIdentifiers ?? [], args.hasher)
|
|
238
218
|
}
|
|
239
219
|
|
|
240
|
-
private createPresentationVerificationCallback(context: IRequiredContext) {
|
|
241
|
-
async function presentationVerificationCallback(
|
|
242
|
-
args: W3CVerifiablePresentation | CompactSdJwtVc,
|
|
243
|
-
presentationSubmission?: PresentationSubmission,
|
|
244
|
-
): Promise<PresentationVerificationResult> {
|
|
245
|
-
let result: IVerifyResult
|
|
246
|
-
if (CredentialMapper.isSdJwtEncoded(args)) {
|
|
247
|
-
try {
|
|
248
|
-
const sdJwtResult = await context.agent.verifySdJwtPresentation({ presentation: args })
|
|
249
|
-
result = {
|
|
250
|
-
verified: 'header' in sdJwtResult,
|
|
251
|
-
error: 'header' in sdJwtResult ? undefined : { message: 'could not verify SD JWT presentation' },
|
|
252
|
-
}
|
|
253
|
-
} catch (error: any) {
|
|
254
|
-
result = {
|
|
255
|
-
verified: false,
|
|
256
|
-
error: { message: error.message },
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
} else {
|
|
260
|
-
// @ts-ignore TODO IVerifiablePresentation has too many union types for Veramo
|
|
261
|
-
result = await context.agent.verifyPresentation({ presentation: args })
|
|
262
|
-
}
|
|
263
|
-
return result
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
return presentationVerificationCallback
|
|
267
|
-
}
|
|
268
|
-
|
|
269
220
|
private async createJarmResponseCallback({
|
|
270
221
|
responseOpts,
|
|
271
222
|
}: {
|
|
@@ -308,6 +259,12 @@ export class OpSession {
|
|
|
308
259
|
}
|
|
309
260
|
|
|
310
261
|
public async sendAuthorizationResponse(args: IOpsSendSiopAuthorizationResponseArgs): Promise<Response> {
|
|
262
|
+
const {
|
|
263
|
+
responseSignerOpts,
|
|
264
|
+
dcqlResponse,
|
|
265
|
+
isFirstParty,
|
|
266
|
+
} = args
|
|
267
|
+
|
|
311
268
|
const resolveOpts: ResolveOpts = this.options.resolveOpts ?? {
|
|
312
269
|
resolver: getAgentResolver(this.context, {
|
|
313
270
|
uniresolverResolution: true,
|
|
@@ -318,30 +275,9 @@ export class OpSession {
|
|
|
318
275
|
if (!resolveOpts.subjectSyntaxTypesSupported || resolveOpts.subjectSyntaxTypesSupported.length === 0) {
|
|
319
276
|
resolveOpts.subjectSyntaxTypesSupported = await this.getSupportedDIDMethods(true)
|
|
320
277
|
}
|
|
321
|
-
//todo: populate with the right verification params. In did-auth-siop we don't have any test that actually passes this parameter
|
|
322
|
-
const verification: Verification = {
|
|
323
|
-
presentationVerificationCallback: this.createPresentationVerificationCallback(this.context),
|
|
324
|
-
}
|
|
325
|
-
const request = await this.getAuthorizationRequest()
|
|
326
|
-
const hasDefinitions = await this.hasPresentationDefinitions()
|
|
327
|
-
if (hasDefinitions) {
|
|
328
|
-
const totalInputDescriptors = request.presentationDefinitions?.reduce((sum, pd) => {
|
|
329
|
-
return sum + pd.definition.input_descriptors.length
|
|
330
|
-
}, 0)
|
|
331
|
-
const totalVCs = args.verifiablePresentations ? this.countVCsInAllVPs(args.verifiablePresentations, args.hasher) : 0
|
|
332
278
|
|
|
333
|
-
|
|
334
|
-
throw Error(
|
|
335
|
-
`Amount of presentations ${args.verifiablePresentations?.length}, doesn't match expected ${request.presentationDefinitions?.length}`,
|
|
336
|
-
)
|
|
337
|
-
} else if (!args.presentationSubmission) {
|
|
338
|
-
throw Error(`Presentation submission is required when verifiable presentations are required`)
|
|
339
|
-
}
|
|
340
|
-
}
|
|
279
|
+
const request = await this.getAuthorizationRequest()
|
|
341
280
|
|
|
342
|
-
const verifiablePresentations = args.verifiablePresentations
|
|
343
|
-
? args.verifiablePresentations.map((vp) => CredentialMapper.storedPresentationToOriginalFormat(vp))
|
|
344
|
-
: []
|
|
345
281
|
const op = await createOP({
|
|
346
282
|
opOptions: {
|
|
347
283
|
...this.options,
|
|
@@ -351,23 +287,16 @@ export class OpSession {
|
|
|
351
287
|
wellknownDIDVerifyCallback: this.options.wellknownDIDVerifyCallback,
|
|
352
288
|
supportedVersions: request.versions,
|
|
353
289
|
},
|
|
354
|
-
idOpts:
|
|
290
|
+
idOpts: responseSignerOpts,
|
|
355
291
|
context: this.context,
|
|
356
292
|
})
|
|
357
293
|
|
|
358
294
|
//TODO change this to use the new functionalities by identifier-resolver and get the jwkIssuer for the responseOpts
|
|
359
|
-
let issuer =
|
|
295
|
+
let issuer = responseSignerOpts.issuer
|
|
360
296
|
const responseOpts = {
|
|
361
|
-
verification,
|
|
362
297
|
issuer,
|
|
363
|
-
...(
|
|
364
|
-
|
|
365
|
-
presentationExchange: {
|
|
366
|
-
verifiablePresentations,
|
|
367
|
-
presentationSubmission: args.presentationSubmission,
|
|
368
|
-
} as PresentationExchangeResponseOpts,
|
|
369
|
-
}),
|
|
370
|
-
dcqlQuery: args.dcqlResponse,
|
|
298
|
+
...(isFirstParty && { isFirstParty }),
|
|
299
|
+
dcqlResponse: dcqlResponse,
|
|
371
300
|
}
|
|
372
301
|
|
|
373
302
|
const authResponse = await op.createAuthorizationResponse(request, responseOpts)
|
|
@@ -379,27 +308,6 @@ export class OpSession {
|
|
|
379
308
|
return response
|
|
380
309
|
}
|
|
381
310
|
}
|
|
382
|
-
|
|
383
|
-
private countVCsInAllVPs(verifiablePresentations: W3CVerifiablePresentation[], hasher?: HasherSync) {
|
|
384
|
-
return verifiablePresentations.reduce((sum, vp) => {
|
|
385
|
-
if (CredentialMapper.isMsoMdocDecodedPresentation(vp) || CredentialMapper.isMsoMdocOid4VPEncoded(vp)) {
|
|
386
|
-
return sum + 1
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
const uvp = CredentialMapper.toUniformPresentation(vp, { hasher: hasher ?? this.options.hasher })
|
|
390
|
-
if (uvp.verifiableCredential?.length) {
|
|
391
|
-
return sum + uvp.verifiableCredential?.length
|
|
392
|
-
}
|
|
393
|
-
const isSdJWT = CredentialMapper.isSdJwtDecodedCredential(uvp)
|
|
394
|
-
if (
|
|
395
|
-
isSdJWT ||
|
|
396
|
-
(uvp.verifiableCredential && !PEX.allowMultipleVCsPerPresentation(uvp.verifiableCredential as Array<OriginalVerifiableCredential>))
|
|
397
|
-
) {
|
|
398
|
-
return sum + 1
|
|
399
|
-
}
|
|
400
|
-
return sum
|
|
401
|
-
}, 0)
|
|
402
|
-
}
|
|
403
311
|
}
|
|
404
312
|
|
|
405
313
|
function convertDidMethod(didMethod: string, didPrefix?: boolean): string {
|
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DcqlResponseOpts,
|
|
3
|
-
PresentationDefinitionWithLocation,
|
|
4
3
|
PresentationSignCallback,
|
|
5
4
|
ResponseMode,
|
|
6
5
|
SupportedVersion,
|
|
7
6
|
URI,
|
|
8
|
-
VerifiablePresentationTypeFormat,
|
|
9
7
|
VerifiedAuthorizationRequest,
|
|
10
8
|
VerifyJwtCallback,
|
|
11
|
-
VPTokenLocation,
|
|
12
9
|
} from '@sphereon/did-auth-siop'
|
|
13
10
|
import { CheckLinkedDomain, ResolveOpts } from '@sphereon/did-auth-siop-adapter'
|
|
14
11
|
import { DIDDocument } from '@sphereon/did-uni-client'
|
|
15
|
-
import { VerifiablePresentationResult } from '@sphereon/pex'
|
|
16
12
|
import { IIdentifierResolution, ManagedIdentifierOptsOrResult } from '@sphereon/ssi-sdk-ext.identifier-resolution'
|
|
17
13
|
import { IJwtService } from '@sphereon/ssi-sdk-ext.jwt-service'
|
|
18
|
-
import { ICredentialStore
|
|
14
|
+
import { ICredentialStore } from '@sphereon/ssi-sdk.credential-store'
|
|
19
15
|
import { Party } from '@sphereon/ssi-sdk.data-store'
|
|
20
16
|
import { IPDManager } from '@sphereon/ssi-sdk.pd-manager'
|
|
21
17
|
import { ISDJwtPlugin } from '@sphereon/ssi-sdk.sd-jwt'
|
|
22
|
-
import { HasherSync,
|
|
18
|
+
import { HasherSync, PresentationSubmission, W3CVerifiablePresentation } from '@sphereon/ssi-types'
|
|
23
19
|
import { VerifyCallback } from '@sphereon/wellknown-dids-client'
|
|
24
20
|
import {
|
|
25
21
|
IAgentContext,
|
|
@@ -49,6 +45,7 @@ import {
|
|
|
49
45
|
Siopv2AuthorizationResponseData,
|
|
50
46
|
} from './siop-service'
|
|
51
47
|
import { ICredentialValidation } from '@sphereon/ssi-sdk.credential-validation'
|
|
48
|
+
import { DcqlPresentation, DcqlQuery } from 'dcql'
|
|
52
49
|
|
|
53
50
|
export const LOGGER_NAMESPACE = 'sphereon:siopv2-oid4vp:op-auth'
|
|
54
51
|
|
|
@@ -81,7 +78,7 @@ export interface IDidAuthSiopOpAuthenticator extends IPluginMethodMap {
|
|
|
81
78
|
export interface IOpSessionArgs {
|
|
82
79
|
sessionId?: string
|
|
83
80
|
requestJwtOrUri: string | URI
|
|
84
|
-
|
|
81
|
+
dcqlQuery?: DcqlQuery
|
|
85
82
|
identifierOptions?: ManagedIdentifierOptsOrResult
|
|
86
83
|
context: IRequiredContext
|
|
87
84
|
op?: IOPOptions
|
|
@@ -90,17 +87,10 @@ export interface IOpSessionArgs {
|
|
|
90
87
|
export interface IAuthRequestDetails {
|
|
91
88
|
rpDIDDocument?: DIDDocument
|
|
92
89
|
id: string
|
|
93
|
-
verifiablePresentationMatches:
|
|
90
|
+
verifiablePresentationMatches: DcqlPresentation[]
|
|
94
91
|
alsoKnownAs?: string[]
|
|
95
92
|
}
|
|
96
93
|
|
|
97
|
-
export interface IPresentationWithDefinition {
|
|
98
|
-
location: VPTokenLocation
|
|
99
|
-
definition: PresentationDefinitionWithLocation
|
|
100
|
-
format: VerifiablePresentationTypeFormat
|
|
101
|
-
presentation: W3CVerifiablePresentation
|
|
102
|
-
}
|
|
103
|
-
|
|
104
94
|
export interface IGetSiopSessionArgs {
|
|
105
95
|
sessionId: string
|
|
106
96
|
}
|
|
@@ -120,7 +110,6 @@ export interface IRemoveCustomApprovalForSiopArgs {
|
|
|
120
110
|
|
|
121
111
|
export interface IOpsSendSiopAuthorizationResponseArgs {
|
|
122
112
|
responseSignerOpts: ManagedIdentifierOptsOrResult
|
|
123
|
-
// verifiedAuthorizationRequest: VerifiedAuthorizationRequest
|
|
124
113
|
presentationSubmission?: PresentationSubmission
|
|
125
114
|
verifiablePresentations?: W3CVerifiablePresentation[]
|
|
126
115
|
dcqlResponse?: DcqlResponseOpts
|
|
@@ -128,10 +117,6 @@ export interface IOpsSendSiopAuthorizationResponseArgs {
|
|
|
128
117
|
isFirstParty?: boolean
|
|
129
118
|
}
|
|
130
119
|
|
|
131
|
-
export enum events {
|
|
132
|
-
DID_SIOP_AUTHENTICATED = 'didSiopAuthenticated',
|
|
133
|
-
}
|
|
134
|
-
|
|
135
120
|
export type IRequiredContext = IAgentContext<
|
|
136
121
|
IDataStoreORM &
|
|
137
122
|
IResolver &
|
|
@@ -155,34 +140,13 @@ export interface IOPOptions {
|
|
|
155
140
|
skipDidResolution?: boolean
|
|
156
141
|
eventEmitter?: EventEmitter
|
|
157
142
|
supportedDIDMethods?: string[]
|
|
158
|
-
|
|
159
143
|
verifyJwtCallback?: VerifyJwtCallback
|
|
160
144
|
wellknownDIDVerifyCallback?: VerifyCallback
|
|
161
|
-
|
|
162
145
|
presentationSignCallback?: PresentationSignCallback
|
|
163
|
-
|
|
164
146
|
resolveOpts?: ResolveOpts
|
|
165
147
|
hasher?: HasherSync
|
|
166
148
|
}
|
|
167
149
|
|
|
168
|
-
/*
|
|
169
|
-
export interface IIdentifierOpts {
|
|
170
|
-
identifier: IIdentifier
|
|
171
|
-
verificationMethodSection?: DIDDocumentSection
|
|
172
|
-
kid?: string
|
|
173
|
-
}*/
|
|
174
|
-
|
|
175
|
-
export interface VerifiableCredentialsWithDefinition {
|
|
176
|
-
definition: PresentationDefinitionWithLocation
|
|
177
|
-
credentials: (UniqueDigitalCredential | OriginalVerifiableCredential)[]
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export interface VerifiablePresentationWithDefinition extends VerifiablePresentationResult {
|
|
181
|
-
definition: PresentationDefinitionWithLocation
|
|
182
|
-
verifiableCredentials: OriginalVerifiableCredential[]
|
|
183
|
-
idOpts: ManagedIdentifierOptsOrResult
|
|
184
|
-
}
|
|
185
|
-
|
|
186
150
|
export interface IOpSessionGetOID4VPArgs {
|
|
187
151
|
allIdentifiers?: string[]
|
|
188
152
|
hasher?: HasherSync
|
|
@@ -194,21 +158,4 @@ export interface IOID4VPArgs {
|
|
|
194
158
|
hasher?: HasherSync
|
|
195
159
|
}
|
|
196
160
|
|
|
197
|
-
export interface IGetPresentationExchangeArgs {
|
|
198
|
-
verifiableCredentials: OriginalVerifiableCredential[]
|
|
199
|
-
allIdentifiers?: string[]
|
|
200
|
-
hasher?: HasherSync
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// It was added here because it's not exported from DCQL anymore
|
|
204
|
-
export type Json =
|
|
205
|
-
| string
|
|
206
|
-
| number
|
|
207
|
-
| boolean
|
|
208
|
-
| null
|
|
209
|
-
| {
|
|
210
|
-
[key: string]: Json
|
|
211
|
-
}
|
|
212
|
-
| Json[]
|
|
213
|
-
|
|
214
161
|
export const DEFAULT_JWT_PROOF_TYPE = 'JwtProof2020'
|
|
@@ -2,9 +2,6 @@ import { IDIDManager, IIdentifier, IResolver, TAgent, TKeyType } from '@veramo/c
|
|
|
2
2
|
import { _ExtendedIKey } from '@veramo/utils'
|
|
3
3
|
import { RequiredContext } from '../siop-service'
|
|
4
4
|
import { SupportedDidMethodEnum } from '@sphereon/ssi-sdk-ext.did-utils'
|
|
5
|
-
import { IContactManager } from '@sphereon/ssi-sdk.contact-manager'
|
|
6
|
-
import { IIssuanceBranding } from '@sphereon/ssi-sdk.issuance-branding'
|
|
7
|
-
import { ICredentialStore } from '@sphereon/ssi-sdk.credential-store'
|
|
8
5
|
|
|
9
6
|
export const DID_PREFIX = 'did'
|
|
10
7
|
|
|
@@ -60,4 +57,3 @@ export type CreateIdentifierOpts = {
|
|
|
60
57
|
}
|
|
61
58
|
|
|
62
59
|
export type DidAgents = TAgent<IResolver & IDIDManager>
|
|
63
|
-
export type SuitableCredentialAgents = TAgent<IContactManager & ICredentialStore & IIssuanceBranding>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
PresentationDefinitionWithLocation,
|
|
3
2
|
PresentationSignCallback,
|
|
4
3
|
RPRegistrationMetadataPayload,
|
|
5
4
|
VerifiedAuthorizationRequest,
|
|
@@ -69,8 +68,7 @@ export type Siopv2AuthorizationRequestData = {
|
|
|
69
68
|
name?: string
|
|
70
69
|
uri?: URL
|
|
71
70
|
clientId?: string
|
|
72
|
-
|
|
73
|
-
dcqlQuery?: DcqlQuery
|
|
71
|
+
dcqlQuery: DcqlQuery
|
|
74
72
|
}
|
|
75
73
|
|
|
76
74
|
export type SelectableCredentialsMap = Map<string, Array<SelectableCredential>>
|
|
@@ -1,45 +1,7 @@
|
|
|
1
|
-
import { CredentialMapper, HasherSync, ICredential,
|
|
1
|
+
import { CredentialMapper, HasherSync, ICredential, OriginalVerifiableCredential } from '@sphereon/ssi-types'
|
|
2
2
|
import { VerifiableCredential } from '@veramo/core'
|
|
3
3
|
import { UniqueDigitalCredential } from '@sphereon/ssi-sdk.credential-store'
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Return the type(s) of a VC minus the VerifiableCredential type which should always be present
|
|
7
|
-
* @param credential The input credential
|
|
8
|
-
*/
|
|
9
|
-
export const getCredentialTypeAsString = (credential: ICredential | VerifiableCredential): string => {
|
|
10
|
-
if (!credential.type) {
|
|
11
|
-
return 'Verifiable Credential'
|
|
12
|
-
} else if (typeof credential.type === 'string') {
|
|
13
|
-
return credential.type
|
|
14
|
-
}
|
|
15
|
-
return credential.type.filter((type: string): boolean => type !== 'VerifiableCredential').join(', ')
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Returns a Unique Verifiable Credential (with hash) as stored in Veramo, based upon matching the id of the input VC or the proof value of the input VC
|
|
20
|
-
* @param uniqueVCs The Unique VCs to search in
|
|
21
|
-
* @param searchVC The VC to search for in the unique VCs array
|
|
22
|
-
*/
|
|
23
|
-
export const getMatchingUniqueDigitalCredential = (
|
|
24
|
-
uniqueVCs: UniqueDigitalCredential[],
|
|
25
|
-
searchVC: OriginalVerifiableCredential,
|
|
26
|
-
): UniqueDigitalCredential | undefined => {
|
|
27
|
-
// Since an ID is optional in a VC according to VCDM, and we really need the matches, we have a fallback match on something which is guaranteed to be unique for any VC (the proof(s))
|
|
28
|
-
return uniqueVCs.find(
|
|
29
|
-
(uniqueVC: UniqueDigitalCredential) =>
|
|
30
|
-
(typeof searchVC !== 'string' &&
|
|
31
|
-
(uniqueVC.id === (<IVerifiableCredential>searchVC).id ||
|
|
32
|
-
(uniqueVC.originalVerifiableCredential as VerifiableCredential).proof === (<IVerifiableCredential>searchVC).proof)) ||
|
|
33
|
-
(typeof searchVC === 'string' && (uniqueVC.uniformVerifiableCredential as VerifiableCredential)?.proof?.jwt === searchVC) ||
|
|
34
|
-
// We are ignoring the signature of the sd-jwt as PEX signs the vc again and it will not match anymore with the jwt in the proof of the stored jsonld vc
|
|
35
|
-
(typeof searchVC === 'string' &&
|
|
36
|
-
CredentialMapper.isSdJwtEncoded(searchVC) &&
|
|
37
|
-
uniqueVC.uniformVerifiableCredential?.proof &&
|
|
38
|
-
'jwt' in uniqueVC.uniformVerifiableCredential.proof &&
|
|
39
|
-
uniqueVC.uniformVerifiableCredential.proof.jwt?.split('.')?.slice(0, 2)?.join('.') === searchVC.split('.')?.slice(0, 2)?.join('.')),
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
5
|
type InputCredential = UniqueDigitalCredential | VerifiableCredential | ICredential | OriginalVerifiableCredential
|
|
44
6
|
|
|
45
7
|
/**
|
package/src/utils/dcql.ts
CHANGED
|
@@ -1,36 +1,39 @@
|
|
|
1
1
|
import { UniqueDigitalCredential } from '@sphereon/ssi-sdk.credential-store'
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
CredentialMapper,
|
|
4
|
+
HasherSync,
|
|
5
|
+
OriginalVerifiableCredential, WrappedMdocCredential,
|
|
6
|
+
type WrappedSdJwtVerifiableCredential, type WrappedW3CVerifiableCredential
|
|
7
|
+
} from '@sphereon/ssi-types'
|
|
8
|
+
import { Dcql } from '@sphereon/did-auth-siop'
|
|
9
|
+
import { DcqlCredential } from 'dcql'
|
|
4
10
|
import { isUniqueDigitalCredential } from './CredentialUtils'
|
|
5
11
|
|
|
6
12
|
export function convertToDcqlCredentials(credential: UniqueDigitalCredential | OriginalVerifiableCredential, hasher?: HasherSync): DcqlCredential {
|
|
7
|
-
let
|
|
13
|
+
let originalVerifiableCredential
|
|
8
14
|
if (isUniqueDigitalCredential(credential)) {
|
|
9
15
|
if (!credential.originalVerifiableCredential) {
|
|
10
16
|
throw new Error('originalVerifiableCredential is not defined in UniqueDigitalCredential')
|
|
11
17
|
}
|
|
12
|
-
|
|
18
|
+
originalVerifiableCredential = CredentialMapper.decodeVerifiableCredential(credential.originalVerifiableCredential, hasher)
|
|
13
19
|
} else {
|
|
14
|
-
|
|
20
|
+
originalVerifiableCredential = CredentialMapper.decodeVerifiableCredential(credential as OriginalVerifiableCredential, hasher)
|
|
15
21
|
}
|
|
16
22
|
|
|
17
|
-
if (!
|
|
23
|
+
if (!originalVerifiableCredential) {
|
|
18
24
|
throw new Error('No payload found')
|
|
19
25
|
}
|
|
20
26
|
|
|
21
|
-
if (
|
|
22
|
-
|
|
27
|
+
if (CredentialMapper.isJwtDecodedCredential(originalVerifiableCredential)) {
|
|
28
|
+
return Dcql.toDcqlJwtCredential(CredentialMapper.toWrappedVerifiableCredential(originalVerifiableCredential) as WrappedW3CVerifiableCredential)
|
|
29
|
+
} else if (CredentialMapper.isSdJwtDecodedCredential(originalVerifiableCredential)) {
|
|
30
|
+
// FIXME: SD-JWT VC vs VCDM2 + SD-JWT would need to be handled here
|
|
31
|
+
return Dcql.toDcqlSdJwtCredential(CredentialMapper.toWrappedVerifiableCredential(originalVerifiableCredential) as WrappedSdJwtVerifiableCredential)
|
|
32
|
+
} else if (CredentialMapper.isMsoMdocDecodedCredential(originalVerifiableCredential)) {
|
|
33
|
+
return Dcql.toDcqlMdocCredential(CredentialMapper.toWrappedVerifiableCredential(originalVerifiableCredential) as WrappedMdocCredential)
|
|
34
|
+
} else if (CredentialMapper.isW3cCredential(originalVerifiableCredential)) {
|
|
35
|
+
return Dcql.toDcqlJsonLdCredential(CredentialMapper.toWrappedVerifiableCredential(originalVerifiableCredential) as WrappedW3CVerifiableCredential)
|
|
23
36
|
}
|
|
24
37
|
|
|
25
|
-
|
|
26
|
-
return { vct: payload.vct, claims: payload, credential_format: 'vc+sd-jwt' } satisfies DcqlSdJwtVcCredential // TODO dc+sd-jwt support?
|
|
27
|
-
} else if ('docType' in payload! && 'namespaces' in payload) {
|
|
28
|
-
// mdoc
|
|
29
|
-
return { docType: payload.docType, namespaces: payload.namespaces, claims: payload }
|
|
30
|
-
} else {
|
|
31
|
-
return {
|
|
32
|
-
claims: payload,
|
|
33
|
-
credential_format: 'jwt_vc_json', // TODO jwt_vc_json-ld support
|
|
34
|
-
} as DcqlW3cVcCredential
|
|
35
|
-
}
|
|
38
|
+
throw Error(`Unable to map credential to DCQL credential. Credential: ${JSON.stringify(originalVerifiableCredential)}`)
|
|
36
39
|
}
|