@sphereon/ssi-sdk.siopv2-oid4vp-op-auth 0.32.1-feature.SPRIND.89.53 → 0.32.1-feature.SSISDK.5.credential.offer.uri.200
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/agent/DidAuthSiopOpAuthenticator.d.ts +6 -1
- package/dist/agent/DidAuthSiopOpAuthenticator.d.ts.map +1 -1
- package/dist/agent/DidAuthSiopOpAuthenticator.js +91 -22
- package/dist/agent/DidAuthSiopOpAuthenticator.js.map +1 -1
- package/dist/services/Siopv2MachineService.d.ts +2 -0
- package/dist/services/Siopv2MachineService.d.ts.map +1 -1
- package/dist/services/Siopv2MachineService.js +97 -7
- package/dist/services/Siopv2MachineService.js.map +1 -1
- package/dist/session/OpSession.d.ts.map +1 -1
- package/dist/session/OpSession.js +2 -2
- package/dist/session/OpSession.js.map +1 -1
- package/dist/types/IDidAuthSiopOpAuthenticator.d.ts +5 -1
- package/dist/types/IDidAuthSiopOpAuthenticator.d.ts.map +1 -1
- package/dist/types/IDidAuthSiopOpAuthenticator.js.map +1 -1
- package/dist/types/siop-service/index.d.ts +2 -0
- package/dist/types/siop-service/index.d.ts.map +1 -1
- package/dist/types/siop-service/index.js.map +1 -1
- package/dist/utils/CredentialUtils.d.ts +23 -0
- package/dist/utils/CredentialUtils.d.ts.map +1 -0
- package/dist/utils/CredentialUtils.js +65 -0
- package/dist/utils/CredentialUtils.js.map +1 -0
- package/dist/utils/dcql.d.ts +5 -0
- package/dist/utils/dcql.d.ts.map +1 -0
- package/dist/utils/dcql.js +37 -0
- package/dist/utils/dcql.js.map +1 -0
- package/package.json +22 -19
- package/src/agent/DidAuthSiopOpAuthenticator.ts +113 -38
- package/src/services/Siopv2MachineService.ts +115 -12
- package/src/session/OpSession.ts +3 -2
- package/src/types/IDidAuthSiopOpAuthenticator.ts +13 -0
- package/src/types/siop-service/index.ts +2 -0
- package/src/utils/CredentialUtils.ts +71 -0
- package/src/utils/dcql.ts +36 -0
|
@@ -2,9 +2,9 @@ import { AuthorizationRequest, SupportedVersion } from '@sphereon/did-auth-siop'
|
|
|
2
2
|
import { IPresentationDefinition, PEX } from '@sphereon/pex'
|
|
3
3
|
import { InputDescriptorV1, InputDescriptorV2, PresentationDefinitionV1, PresentationDefinitionV2 } from '@sphereon/pex-models'
|
|
4
4
|
import { isOID4VCIssuerIdentifier, ManagedIdentifierOptsOrResult } from '@sphereon/ssi-sdk-ext.identifier-resolution'
|
|
5
|
-
import { verifiableCredentialForRoleFilter } from '@sphereon/ssi-sdk.credential-store'
|
|
5
|
+
import { UniqueDigitalCredential, verifiableCredentialForRoleFilter } from '@sphereon/ssi-sdk.credential-store'
|
|
6
6
|
import { ConnectionType, CredentialRole } from '@sphereon/ssi-sdk.data-store'
|
|
7
|
-
import { CredentialMapper, Hasher, Loggers, PresentationSubmission } from '@sphereon/ssi-types'
|
|
7
|
+
import { CredentialMapper, Hasher, Loggers, OriginalVerifiableCredential, PresentationSubmission } from '@sphereon/ssi-types'
|
|
8
8
|
import { OID4VP, OpSession } from '../session'
|
|
9
9
|
import {
|
|
10
10
|
DidAgents,
|
|
@@ -20,6 +20,9 @@ import {
|
|
|
20
20
|
import { IAgentContext, IDIDManager } from '@veramo/core'
|
|
21
21
|
import { getOrCreatePrimaryIdentifier, SupportedDidMethodEnum } from '@sphereon/ssi-sdk-ext.did-utils'
|
|
22
22
|
import { encodeJoseBlob } from '@sphereon/ssi-sdk.core'
|
|
23
|
+
import { DcqlCredential, DcqlQuery, DcqlCredentialPresentation, DcqlPresentation } from 'dcql'
|
|
24
|
+
import { convertToDcqlCredentials } from '../utils/dcql'
|
|
25
|
+
import { getOriginalVerifiableCredential } from '../utils/CredentialUtils'
|
|
23
26
|
|
|
24
27
|
export const logger = Loggers.DEFAULT.get(LOGGER_NAMESPACE)
|
|
25
28
|
|
|
@@ -50,6 +53,7 @@ export const siopSendAuthorizationResponse = async (
|
|
|
50
53
|
idOpts?: ManagedIdentifierOptsOrResult
|
|
51
54
|
isFirstParty?: boolean
|
|
52
55
|
hasher?: Hasher
|
|
56
|
+
dcqlQuery?: DcqlQuery
|
|
53
57
|
},
|
|
54
58
|
context: RequiredContext,
|
|
55
59
|
) => {
|
|
@@ -155,17 +159,116 @@ export const siopSendAuthorizationResponse = async (
|
|
|
155
159
|
|
|
156
160
|
idOpts = presentationsAndDefs[0].idOpts
|
|
157
161
|
presentationSubmission = presentationsAndDefs[0].presentationSubmission
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
162
|
+
|
|
163
|
+
logger.log(`Definitions and locations:`, JSON.stringify(presentationsAndDefs?.[0]?.verifiablePresentations, null, 2))
|
|
164
|
+
logger.log(`Presentation Submission:`, JSON.stringify(presentationSubmission, null, 2))
|
|
165
|
+
const mergedVerifiablePresentations = presentationsAndDefs?.flatMap((pd) => pd.verifiablePresentations) || []
|
|
166
|
+
return await session.sendAuthorizationResponse({
|
|
167
|
+
...(presentationsAndDefs && { verifiablePresentations: mergedVerifiablePresentations }),
|
|
168
|
+
...(presentationSubmission && { presentationSubmission }),
|
|
169
|
+
// todo: Change issuer value in case we do not use identifier. Use key.meta.jwkThumbprint then
|
|
170
|
+
responseSignerOpts: idOpts!,
|
|
167
171
|
isFirstParty,
|
|
168
|
-
|
|
172
|
+
})
|
|
173
|
+
} else if (request.dcqlQuery) {
|
|
174
|
+
if (args.verifiableCredentialsWithDefinition !== undefined && args.verifiableCredentialsWithDefinition !== null) {
|
|
175
|
+
const vcs = args.verifiableCredentialsWithDefinition.flatMap((vcd) => vcd.credentials)
|
|
176
|
+
const domain =
|
|
177
|
+
((await request.authorizationRequest.getMergedProperty('client_id')) as string) ??
|
|
178
|
+
request.issuer ??
|
|
179
|
+
(request.versions.includes(SupportedVersion.JWT_VC_PRESENTATION_PROFILE_v1)
|
|
180
|
+
? 'https://self-issued.me/v2/openid-vc'
|
|
181
|
+
: 'https://self-issued.me/v2')
|
|
182
|
+
logger.debug(`NONCE: ${session.nonce}, domain: ${domain}`)
|
|
183
|
+
|
|
184
|
+
const firstUniqueDC = vcs[0]
|
|
185
|
+
if (typeof firstUniqueDC !== 'object' || !('digitalCredential' in firstUniqueDC)) {
|
|
186
|
+
return Promise.reject(Error('SiopMachine only supports UniqueDigitalCredentials for now'))
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
let identifier: ManagedIdentifierOptsOrResult
|
|
190
|
+
const digitalCredential = firstUniqueDC.digitalCredential
|
|
191
|
+
const firstVC = firstUniqueDC.uniformVerifiableCredential
|
|
192
|
+
const holder = CredentialMapper.isSdJwtDecodedCredential(firstVC)
|
|
193
|
+
? firstVC.decodedPayload.cnf?.jwk
|
|
194
|
+
? //TODO SDK-19: convert the JWK to hex and search for the appropriate key and associated DID
|
|
195
|
+
//doesn't apply to did:jwk only, as you can represent any DID key as a JWK. So whenever you encounter a JWK it doesn't mean it had to come from a did:jwk in the system. It just can always be represented as a did:jwk
|
|
196
|
+
`did:jwk:${encodeJoseBlob(firstVC.decodedPayload.cnf?.jwk)}#0`
|
|
197
|
+
: firstVC.decodedPayload.sub
|
|
198
|
+
: Array.isArray(firstVC.credentialSubject)
|
|
199
|
+
? firstVC.credentialSubject[0].id
|
|
200
|
+
: firstVC.credentialSubject.id
|
|
201
|
+
if (!digitalCredential.kmsKeyRef) {
|
|
202
|
+
// In case the store does not have the kmsKeyRef lets search for the holder
|
|
203
|
+
|
|
204
|
+
if (!holder) {
|
|
205
|
+
return Promise.reject(`No holder found and no kmsKeyRef in DB. Cannot determine identifier to use`)
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
identifier = await session.context.agent.identifierManagedGet({ identifier: holder })
|
|
209
|
+
} catch (e) {
|
|
210
|
+
logger.debug(`Holder DID not found: ${holder}`)
|
|
211
|
+
throw e
|
|
212
|
+
}
|
|
213
|
+
} else if (isOID4VCIssuerIdentifier(digitalCredential.kmsKeyRef)) {
|
|
214
|
+
identifier = await session.context.agent.identifierManagedGetByOID4VCIssuer({
|
|
215
|
+
identifier: firstUniqueDC.digitalCredential.kmsKeyRef,
|
|
216
|
+
})
|
|
217
|
+
} else {
|
|
218
|
+
switch (digitalCredential.subjectCorrelationType) {
|
|
219
|
+
case 'DID':
|
|
220
|
+
identifier = await session.context.agent.identifierManagedGetByDid({
|
|
221
|
+
identifier: digitalCredential.subjectCorrelationId ?? holder,
|
|
222
|
+
kmsKeyRef: digitalCredential.kmsKeyRef,
|
|
223
|
+
})
|
|
224
|
+
break
|
|
225
|
+
// TODO other implementations?
|
|
226
|
+
default:
|
|
227
|
+
// Since we are using the kmsKeyRef we will find the KID regardless of the identifier. We set it for later access though
|
|
228
|
+
identifier = await session.context.agent.identifierManagedGetByKid({
|
|
229
|
+
identifier: digitalCredential.subjectCorrelationId ?? holder ?? digitalCredential.kmsKeyRef,
|
|
230
|
+
kmsKeyRef: digitalCredential.kmsKeyRef,
|
|
231
|
+
})
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
console.log(`Identifier`, identifier)
|
|
235
|
+
|
|
236
|
+
const dcqlRepresentations: DcqlCredential[] = []
|
|
237
|
+
vcs.forEach((vc: UniqueDigitalCredential | OriginalVerifiableCredential) => {
|
|
238
|
+
const rep = convertToDcqlCredentials(vc, args.hasher)
|
|
239
|
+
if (rep) {
|
|
240
|
+
dcqlRepresentations.push(rep)
|
|
241
|
+
}
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
const queryResult = DcqlQuery.query(request.dcqlQuery, dcqlRepresentations)
|
|
245
|
+
const presentation: Record<string, DcqlCredentialPresentation> = {}
|
|
246
|
+
|
|
247
|
+
for (const [key, value] of Object.entries(queryResult.credential_matches)) {
|
|
248
|
+
const allMatches = Array.isArray(value) ? value : [value]
|
|
249
|
+
allMatches.forEach((match) => {
|
|
250
|
+
if (match.success) {
|
|
251
|
+
const originalCredential = getOriginalVerifiableCredential(vcs[match.input_credential_index])
|
|
252
|
+
if (!originalCredential) {
|
|
253
|
+
throw new Error(`Index ${match.input_credential_index} out of range in credentials array`)
|
|
254
|
+
}
|
|
255
|
+
presentation[key] =
|
|
256
|
+
(originalCredential as any)['compactSdJwtVc'] !== undefined ? (originalCredential as any).compactSdJwtVc : originalCredential
|
|
257
|
+
}
|
|
258
|
+
})
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const response = session.sendAuthorizationResponse({
|
|
262
|
+
responseSignerOpts: identifier,
|
|
263
|
+
...{ dcqlQuery: { dcqlPresentation: DcqlPresentation.parse(presentation) } },
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
logger.debug(`Response: `, response)
|
|
267
|
+
|
|
268
|
+
return response
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
throw Error('Presentation Definition or DCQL is required')
|
|
169
272
|
}
|
|
170
273
|
|
|
171
274
|
function buildPartialPD(
|
package/src/session/OpSession.ts
CHANGED
|
@@ -293,8 +293,8 @@ export class OpSession {
|
|
|
293
293
|
.jwtEncryptJweCompactJwt({
|
|
294
294
|
recipientKey,
|
|
295
295
|
protectedHeader: {},
|
|
296
|
-
alg: requestObjectPayload.client_metadata.authorization_encrypted_response_alg as JweAlg | undefined ?? 'ECDH-ES',
|
|
297
|
-
enc: requestObjectPayload.client_metadata.authorization_encrypted_response_enc as JweEnc | undefined ?? 'A256GCM',
|
|
296
|
+
alg: (requestObjectPayload.client_metadata.authorization_encrypted_response_alg as JweAlg | undefined) ?? 'ECDH-ES',
|
|
297
|
+
enc: (requestObjectPayload.client_metadata.authorization_encrypted_response_enc as JweEnc | undefined) ?? 'A256GCM',
|
|
298
298
|
apv: encodeBase64url(opts.requestObjectPayload.nonce),
|
|
299
299
|
apu: encodeBase64url(v4()),
|
|
300
300
|
payload: authResponse,
|
|
@@ -367,6 +367,7 @@ export class OpSession {
|
|
|
367
367
|
presentationSubmission: args.presentationSubmission,
|
|
368
368
|
} as PresentationExchangeResponseOpts,
|
|
369
369
|
}),
|
|
370
|
+
dcqlQuery: args.dcqlResponse,
|
|
370
371
|
}
|
|
371
372
|
|
|
372
373
|
const authResponse = await op.createAuthorizationResponse(request, responseOpts)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
DcqlResponseOpts,
|
|
2
3
|
PresentationDefinitionWithLocation,
|
|
3
4
|
PresentationSignCallback,
|
|
4
5
|
ResponseMode,
|
|
@@ -122,6 +123,7 @@ export interface IOpsSendSiopAuthorizationResponseArgs {
|
|
|
122
123
|
// verifiedAuthorizationRequest: VerifiedAuthorizationRequest
|
|
123
124
|
presentationSubmission?: PresentationSubmission
|
|
124
125
|
verifiablePresentations?: W3CVerifiablePresentation[]
|
|
126
|
+
dcqlResponse?: DcqlResponseOpts
|
|
125
127
|
hasher?: Hasher
|
|
126
128
|
isFirstParty?: boolean
|
|
127
129
|
}
|
|
@@ -198,4 +200,15 @@ export interface IGetPresentationExchangeArgs {
|
|
|
198
200
|
hasher?: Hasher
|
|
199
201
|
}
|
|
200
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
|
+
|
|
201
214
|
export const DEFAULT_JWT_PROOF_TYPE = 'JwtProof2020'
|
|
@@ -11,6 +11,7 @@ import { IIssuanceBranding } from '@sphereon/ssi-sdk.issuance-branding'
|
|
|
11
11
|
import { IAgentContext, IDIDManager, IIdentifier, IResolver } from '@veramo/core'
|
|
12
12
|
import { IDidAuthSiopOpAuthenticator } from '../IDidAuthSiopOpAuthenticator'
|
|
13
13
|
import { Siopv2MachineContext, Siopv2MachineInterpreter, Siopv2MachineState } from '../machine'
|
|
14
|
+
import { DcqlQuery } from 'dcql'
|
|
14
15
|
import { Hasher } from '@sphereon/ssi-types'
|
|
15
16
|
|
|
16
17
|
export type DidAuthSiopOpAuthenticatorOptions = {
|
|
@@ -68,6 +69,7 @@ export type Siopv2AuthorizationRequestData = {
|
|
|
68
69
|
uri?: URL
|
|
69
70
|
clientId?: string
|
|
70
71
|
presentationDefinitions?: PresentationDefinitionWithLocation[]
|
|
72
|
+
dcqlQuery?: DcqlQuery
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
export type SelectableCredentialsMap = Map<string, Array<SelectableCredential>>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { CredentialMapper, Hasher, ICredential, IVerifiableCredential, OriginalVerifiableCredential } from '@sphereon/ssi-types'
|
|
2
|
+
import { VerifiableCredential } from '@veramo/core'
|
|
3
|
+
import { UniqueDigitalCredential } from '@sphereon/ssi-sdk.credential-store'
|
|
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
|
+
type InputCredential = UniqueDigitalCredential | VerifiableCredential | ICredential | OriginalVerifiableCredential
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Get an original verifiable credential. Maps to wrapped Verifiable Credential first, to get an original JWT as Veramo stores these with a special proof value
|
|
47
|
+
* @param credential The input VC
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
export const getOriginalVerifiableCredential = (credential: InputCredential): OriginalVerifiableCredential => {
|
|
51
|
+
if (isUniqueDigitalCredential(credential)) {
|
|
52
|
+
if (!credential.originalVerifiableCredential) {
|
|
53
|
+
throw new Error('originalVerifiableCredential is not defined in UniqueDigitalCredential')
|
|
54
|
+
}
|
|
55
|
+
return getCredentialFromProofOrWrapped(credential.originalVerifiableCredential)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return getCredentialFromProofOrWrapped(credential)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const getCredentialFromProofOrWrapped = (cred: any, hasher?: Hasher): OriginalVerifiableCredential => {
|
|
62
|
+
if (typeof cred === 'object' && 'proof' in cred && 'jwt' in cred.proof && CredentialMapper.isSdJwtEncoded(cred.proof.jwt)) {
|
|
63
|
+
return cred.proof.jwt
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return CredentialMapper.toWrappedVerifiableCredential(cred as OriginalVerifiableCredential, { hasher }).original
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const isUniqueDigitalCredential = (credential: InputCredential): credential is UniqueDigitalCredential => {
|
|
70
|
+
return (credential as UniqueDigitalCredential).digitalCredential !== undefined
|
|
71
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { UniqueDigitalCredential } from '@sphereon/ssi-sdk.credential-store'
|
|
2
|
+
import { DcqlCredential, DcqlSdJwtVcCredential, DcqlW3cVcCredential } from 'dcql'
|
|
3
|
+
import { CredentialMapper, Hasher, OriginalVerifiableCredential } from '@sphereon/ssi-types'
|
|
4
|
+
import { isUniqueDigitalCredential } from './CredentialUtils'
|
|
5
|
+
|
|
6
|
+
export function convertToDcqlCredentials(credential: UniqueDigitalCredential | OriginalVerifiableCredential, hasher?: Hasher): DcqlCredential {
|
|
7
|
+
let payload
|
|
8
|
+
if (isUniqueDigitalCredential(credential)) {
|
|
9
|
+
if (!credential.originalVerifiableCredential) {
|
|
10
|
+
throw new Error('originalVerifiableCredential is not defined in UniqueDigitalCredential')
|
|
11
|
+
}
|
|
12
|
+
payload = CredentialMapper.decodeVerifiableCredential(credential.originalVerifiableCredential, hasher)
|
|
13
|
+
} else {
|
|
14
|
+
payload = CredentialMapper.decodeVerifiableCredential(credential as OriginalVerifiableCredential, hasher)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (!payload) {
|
|
18
|
+
throw new Error('No payload found')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if ('decodedPayload' in payload && payload.decodedPayload) {
|
|
22
|
+
payload = payload.decodedPayload
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if ('vct' in payload!) {
|
|
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
|
+
}
|
|
36
|
+
}
|