@sphereon/ssi-sdk.siopv2-oid4vp-op-auth 0.34.1-fix.226 → 0.34.1-fix.247
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 +55 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +46 -3
- package/dist/index.js.map +1 -1
- package/package.json +22 -22
- package/src/agent/DidAuthSiopOpAuthenticator.ts +1 -1
- package/src/machine/Siopv2Machine.ts +1 -1
- package/src/services/Siopv2MachineService.ts +56 -3
- package/src/session/OID4VP.ts +183 -184
- package/src/types/IDidAuthSiopOpAuthenticator.ts +1 -1
- package/src/types/machine/index.ts +1 -1
- package/src/types/siop-service/index.ts +11 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sphereon/ssi-sdk.siopv2-oid4vp-op-auth",
|
|
3
|
-
"version": "0.34.1-fix.
|
|
3
|
+
"version": "0.34.1-fix.247+6c4b1882",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -26,26 +26,26 @@
|
|
|
26
26
|
"build": "tsup --config ../../tsup.config.ts --tsconfig ../../tsconfig.tsup.json"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@sphereon/did-auth-siop": "0.19.1-feature.DIIPv4.
|
|
30
|
-
"@sphereon/did-auth-siop-adapter": "0.19.1-feature.DIIPv4.
|
|
31
|
-
"@sphereon/oid4vc-common": "0.19.1-feature.DIIPv4.
|
|
29
|
+
"@sphereon/did-auth-siop": "0.19.1-feature.DIIPv4.173",
|
|
30
|
+
"@sphereon/did-auth-siop-adapter": "0.19.1-feature.DIIPv4.173",
|
|
31
|
+
"@sphereon/oid4vc-common": "0.19.1-feature.DIIPv4.173",
|
|
32
32
|
"@sphereon/pex": "5.0.0-unstable.28",
|
|
33
33
|
"@sphereon/pex-models": "^2.3.2",
|
|
34
|
-
"@sphereon/ssi-sdk-ext.did-utils": "0.34.1-fix.
|
|
35
|
-
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.34.1-fix.
|
|
36
|
-
"@sphereon/ssi-sdk-ext.jwt-service": "0.34.1-fix.
|
|
37
|
-
"@sphereon/ssi-sdk.contact-manager": "0.34.1-fix.
|
|
38
|
-
"@sphereon/ssi-sdk.core": "0.34.1-fix.
|
|
39
|
-
"@sphereon/ssi-sdk.credential-store": "0.34.1-fix.
|
|
40
|
-
"@sphereon/ssi-sdk.credential-validation": "0.34.1-fix.
|
|
41
|
-
"@sphereon/ssi-sdk.data-store": "0.34.1-fix.
|
|
42
|
-
"@sphereon/ssi-sdk.issuance-branding": "0.34.1-fix.
|
|
43
|
-
"@sphereon/ssi-sdk.pd-manager": "0.34.1-fix.
|
|
44
|
-
"@sphereon/ssi-sdk.presentation-exchange": "0.34.1-fix.
|
|
45
|
-
"@sphereon/ssi-sdk.sd-jwt": "0.34.1-fix.
|
|
46
|
-
"@sphereon/ssi-sdk.siopv2-oid4vp-common": "0.34.1-fix.
|
|
47
|
-
"@sphereon/ssi-sdk.xstate-machine-persistence": "0.34.1-fix.
|
|
48
|
-
"@sphereon/ssi-types": "0.34.1-fix.
|
|
34
|
+
"@sphereon/ssi-sdk-ext.did-utils": "0.34.1-fix.247+6c4b1882",
|
|
35
|
+
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.34.1-fix.247+6c4b1882",
|
|
36
|
+
"@sphereon/ssi-sdk-ext.jwt-service": "0.34.1-fix.247+6c4b1882",
|
|
37
|
+
"@sphereon/ssi-sdk.contact-manager": "0.34.1-fix.247+6c4b1882",
|
|
38
|
+
"@sphereon/ssi-sdk.core": "0.34.1-fix.247+6c4b1882",
|
|
39
|
+
"@sphereon/ssi-sdk.credential-store": "0.34.1-fix.247+6c4b1882",
|
|
40
|
+
"@sphereon/ssi-sdk.credential-validation": "0.34.1-fix.247+6c4b1882",
|
|
41
|
+
"@sphereon/ssi-sdk.data-store-types": "0.34.1-fix.247+6c4b1882",
|
|
42
|
+
"@sphereon/ssi-sdk.issuance-branding": "0.34.1-fix.247+6c4b1882",
|
|
43
|
+
"@sphereon/ssi-sdk.pd-manager": "0.34.1-fix.247+6c4b1882",
|
|
44
|
+
"@sphereon/ssi-sdk.presentation-exchange": "0.34.1-fix.247+6c4b1882",
|
|
45
|
+
"@sphereon/ssi-sdk.sd-jwt": "0.34.1-fix.247+6c4b1882",
|
|
46
|
+
"@sphereon/ssi-sdk.siopv2-oid4vp-common": "0.34.1-fix.247+6c4b1882",
|
|
47
|
+
"@sphereon/ssi-sdk.xstate-machine-persistence": "0.34.1-fix.247+6c4b1882",
|
|
48
|
+
"@sphereon/ssi-types": "0.34.1-fix.247+6c4b1882",
|
|
49
49
|
"@sphereon/wellknown-dids-client": "^0.1.3",
|
|
50
50
|
"@veramo/core": "4.2.0",
|
|
51
51
|
"@veramo/credential-w3c": "4.2.0",
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@sphereon/did-uni-client": "^0.6.3",
|
|
62
|
-
"@sphereon/ssi-sdk-ext.did-resolver-jwk": "0.34.1-fix.
|
|
63
|
-
"@sphereon/ssi-sdk.agent-config": "0.34.1-fix.
|
|
62
|
+
"@sphereon/ssi-sdk-ext.did-resolver-jwk": "0.34.1-fix.247+6c4b1882",
|
|
63
|
+
"@sphereon/ssi-sdk.agent-config": "0.34.1-fix.247+6c4b1882",
|
|
64
64
|
"@types/i18n-js": "^3.8.9",
|
|
65
65
|
"@types/lodash.memoize": "^4.1.9",
|
|
66
66
|
"@types/sha.js": "^2.4.4",
|
|
@@ -102,5 +102,5 @@
|
|
|
102
102
|
"OpenID Connect",
|
|
103
103
|
"Authenticator"
|
|
104
104
|
],
|
|
105
|
-
"gitHead": "
|
|
105
|
+
"gitHead": "6c4b188290980043b16a2aecce8bb0670d6e8ef2"
|
|
106
106
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { decodeUriAsJson, PresentationSignCallback, VerifiedAuthorizationRequest } from '@sphereon/did-auth-siop'
|
|
2
|
-
import { ConnectionType, CorrelationIdentifierType, Identity, IdentityOrigin, NonPersistedIdentity, Party } from '@sphereon/ssi-sdk.data-store'
|
|
2
|
+
import { ConnectionType, CorrelationIdentifierType, Identity, IdentityOrigin, NonPersistedIdentity, Party } from '@sphereon/ssi-sdk.data-store-types'
|
|
3
3
|
import { HasherSync, Loggers, CredentialRole } from '@sphereon/ssi-types'
|
|
4
4
|
import { IAgentPlugin } from '@veramo/core'
|
|
5
5
|
import { v4 as uuidv4 } from 'uuid'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { VerifiedAuthorizationRequest } from '@sphereon/did-auth-siop'
|
|
2
|
-
import { DidAuthConfig, Identity, Party } from '@sphereon/ssi-sdk.data-store'
|
|
2
|
+
import { DidAuthConfig, Identity, Party } from '@sphereon/ssi-sdk.data-store-types'
|
|
3
3
|
import { assign, createMachine, DoneInvokeEvent, interpret } from 'xstate'
|
|
4
4
|
import { translate } from '../localization/Localization'
|
|
5
5
|
import { ErrorDetails } from '../types'
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { AuthorizationRequest
|
|
1
|
+
import { AuthorizationRequest } from '@sphereon/did-auth-siop'
|
|
2
|
+
import type { PartialSdJwtDecodedVerifiableCredential, PartialSdJwtKbJwt } from '@sphereon/pex/dist/main/lib/index.js'
|
|
3
|
+
import { calculateSdHash } from '@sphereon/pex/dist/main/lib/utils/index.js'
|
|
2
4
|
import { getOrCreatePrimaryIdentifier, SupportedDidMethodEnum } from '@sphereon/ssi-sdk-ext.did-utils'
|
|
3
5
|
import { isOID4VCIssuerIdentifier, ManagedIdentifierOptsOrResult } from '@sphereon/ssi-sdk-ext.identifier-resolution'
|
|
4
6
|
import { encodeJoseBlob } from '@sphereon/ssi-sdk.core'
|
|
5
7
|
import { UniqueDigitalCredential, verifiableCredentialForRoleFilter } from '@sphereon/ssi-sdk.credential-store'
|
|
6
|
-
import { ConnectionType } from '@sphereon/ssi-sdk.data-store'
|
|
8
|
+
import { ConnectionType } from '@sphereon/ssi-sdk.data-store-types'
|
|
9
|
+
import { defaultGenerateDigest } from '@sphereon/ssi-sdk.sd-jwt'
|
|
7
10
|
import {
|
|
8
11
|
CredentialMapper,
|
|
9
12
|
CredentialRole,
|
|
@@ -18,6 +21,8 @@ import { OpSession } from '../session'
|
|
|
18
21
|
import { LOGGER_NAMESPACE, RequiredContext, SelectableCredential, SelectableCredentialsMap, Siopv2HolderEvent } from '../types'
|
|
19
22
|
import { convertToDcqlCredentials } from '../utils/dcql'
|
|
20
23
|
|
|
24
|
+
const CLOCK_SKEW = 120
|
|
25
|
+
|
|
21
26
|
export const logger = Loggers.DEFAULT.get(LOGGER_NAMESPACE)
|
|
22
27
|
|
|
23
28
|
// @ts-ignore
|
|
@@ -140,8 +145,26 @@ export const siopSendAuthorizationResponse = async (
|
|
|
140
145
|
if (!originalVc) {
|
|
141
146
|
continue
|
|
142
147
|
}
|
|
148
|
+
// FIXME SSISDK-44
|
|
149
|
+
const decodedSdJwt = await CredentialMapper.decodeSdJwtVcAsync(originalVc as string, defaultGenerateDigest)
|
|
150
|
+
const updatedSdJwt = updateSdJwtCredential(decodedSdJwt, request.requestObject?.getPayload()?.nonce, domain)
|
|
151
|
+
|
|
152
|
+
const presentationResult = await context.agent.createSdJwtPresentation({
|
|
153
|
+
presentation: updatedSdJwt.compactSdJwtVc,
|
|
154
|
+
kb: {
|
|
155
|
+
payload: {
|
|
156
|
+
...updatedSdJwt.kbJwt?.payload,
|
|
157
|
+
// FIXME SSISDK-44
|
|
158
|
+
nonce: updatedSdJwt.kbJwt?.payload.nonce ?? request.requestObject!.getPayload()!.nonce,
|
|
159
|
+
// FIXME SSISDK-44
|
|
160
|
+
aud: updatedSdJwt.kbJwt?.payload.aud ?? domain,
|
|
161
|
+
iat: updatedSdJwt.kbJwt?.payload?.iat ?? Math.floor(Date.now() / 1000 - CLOCK_SKEW),
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
})
|
|
165
|
+
|
|
143
166
|
if (originalVc) {
|
|
144
|
-
presentation[key] =
|
|
167
|
+
presentation[key] = presentationResult.presentation
|
|
145
168
|
}
|
|
146
169
|
}
|
|
147
170
|
}
|
|
@@ -223,3 +246,33 @@ export const translateCorrelationIdToName = async (correlationId: string, contex
|
|
|
223
246
|
|
|
224
247
|
return contacts[0].contact.displayName
|
|
225
248
|
}
|
|
249
|
+
|
|
250
|
+
const updateSdJwtCredential = (
|
|
251
|
+
credential: SdJwtDecodedVerifiableCredential,
|
|
252
|
+
nonce?: string,
|
|
253
|
+
aud?: string,
|
|
254
|
+
): PartialSdJwtDecodedVerifiableCredential => {
|
|
255
|
+
const sdJwtCredential = credential as SdJwtDecodedVerifiableCredential
|
|
256
|
+
|
|
257
|
+
// extract sd_alg or default to sha-256
|
|
258
|
+
const hashAlg = sdJwtCredential.signedPayload._sd_alg ?? 'sha-256'
|
|
259
|
+
const sdHash = calculateSdHash(sdJwtCredential.compactSdJwtVc, hashAlg, defaultGenerateDigest)
|
|
260
|
+
|
|
261
|
+
const kbJwt = {
|
|
262
|
+
// alg MUST be set by the signer
|
|
263
|
+
header: {
|
|
264
|
+
typ: 'kb+jwt',
|
|
265
|
+
},
|
|
266
|
+
payload: {
|
|
267
|
+
iat: Math.floor(new Date().getTime() / 1000),
|
|
268
|
+
sd_hash: sdHash,
|
|
269
|
+
...(nonce && { nonce }),
|
|
270
|
+
...(aud && { aud }),
|
|
271
|
+
},
|
|
272
|
+
} satisfies PartialSdJwtKbJwt
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
...sdJwtCredential,
|
|
276
|
+
kbJwt,
|
|
277
|
+
} satisfies PartialSdJwtDecodedVerifiableCredential
|
|
278
|
+
}
|
package/src/session/OID4VP.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// // ProofOptions
|
|
12
12
|
// } from '@sphereon/ssi-sdk.core'
|
|
13
13
|
//import { UniqueDigitalCredential, verifiableCredentialForRoleFilter } from '@sphereon/ssi-sdk.credential-store'
|
|
14
|
-
//import { CredentialRole, FindDigitalCredentialArgs } from '@sphereon/ssi-sdk.data-store'
|
|
14
|
+
//import { CredentialRole, FindDigitalCredentialArgs } from '@sphereon/ssi-sdk.data-store-types'
|
|
15
15
|
import {
|
|
16
16
|
//CompactJWT,
|
|
17
17
|
HasherSync,
|
|
@@ -38,7 +38,6 @@ export class OID4VP {
|
|
|
38
38
|
// const { session,
|
|
39
39
|
// // allIdentifiers, hasher = defaultHasher
|
|
40
40
|
// } = args
|
|
41
|
-
|
|
42
41
|
//this.session = session
|
|
43
42
|
// this.allIdentifiers = allIdentifiers ?? []
|
|
44
43
|
// this.hasher = hasher
|
|
@@ -85,142 +84,142 @@ export class OID4VP {
|
|
|
85
84
|
// return await Promise.all(credentialsWithDefinitions.map((cred) => this.createVerifiablePresentation(credentialRole, cred, opts)))
|
|
86
85
|
// }
|
|
87
86
|
|
|
88
|
-
// public async createVerifiablePresentation(
|
|
89
|
-
// credentialRole: CredentialRole,
|
|
90
|
-
// selectedVerifiableCredentials: VerifiableCredentialsWithDefinition,
|
|
91
|
-
// opts?: {
|
|
92
|
-
// forceNoCredentialsInVP?: boolean // Allow to create a VP without credentials, like EBSI is using it. Defaults to false
|
|
93
|
-
// restrictToFormats?: Format
|
|
94
|
-
// restrictToDIDMethods?: string[]
|
|
95
|
-
// proofOpts?: ProofOptions
|
|
96
|
-
// idOpts?: ManagedIdentifierOptsOrResult
|
|
97
|
-
// skipDidResolution?: boolean
|
|
98
|
-
// holder?: string
|
|
99
|
-
// subjectIsHolder?: boolean
|
|
100
|
-
// applyFilter?: boolean
|
|
101
|
-
// hasher?: HasherSync
|
|
102
|
-
// },
|
|
103
|
-
// ): Promise<VerifiablePresentationWithDefinition> {
|
|
104
|
-
// const { subjectIsHolder, holder, forceNoCredentialsInVP = false } = { ...opts }
|
|
105
|
-
// if (subjectIsHolder && holder) {
|
|
106
|
-
// throw Error('Cannot both have subject is holder and a holderDID value at the same time (programming error)')
|
|
107
|
-
// }
|
|
108
|
-
// if (forceNoCredentialsInVP) {
|
|
109
|
-
// selectedVerifiableCredentials.credentials = []
|
|
110
|
-
// } else if (!selectedVerifiableCredentials?.credentials || selectedVerifiableCredentials.credentials.length === 0) {
|
|
111
|
-
// throw Error('No verifiable verifiableCredentials provided for presentation definition')
|
|
112
|
-
// }
|
|
113
|
-
//
|
|
114
|
-
// // const proofOptions: ProofOptions = {
|
|
115
|
-
// // ...opts?.proofOpts,
|
|
116
|
-
// // challenge: opts?.proofOpts?.nonce ?? opts?.proofOpts?.challenge ?? this.session.nonce,
|
|
117
|
-
// // domain: opts?.proofOpts?.domain ?? (await this.session.getRedirectUri()),
|
|
118
|
-
// // }
|
|
119
|
-
//
|
|
120
|
-
// let idOpts = opts?.idOpts
|
|
121
|
-
// if (!idOpts) {
|
|
122
|
-
// if (opts?.subjectIsHolder) {
|
|
123
|
-
// if (forceNoCredentialsInVP) {
|
|
124
|
-
// return Promise.reject(
|
|
125
|
-
// Error(
|
|
126
|
-
// `Cannot have subject is holder, when force no credentials is being used, as we could never determine the holder then. Please provide holderDID`,
|
|
127
|
-
// ),
|
|
128
|
-
// )
|
|
129
|
-
// }
|
|
130
|
-
// const firstUniqueDC = selectedVerifiableCredentials.credentials[0]
|
|
131
|
-
// // const firstVC = firstUniqueDC.uniformVerifiableCredential!
|
|
132
|
-
// if (typeof firstUniqueDC !== 'object' || !('digitalCredential' in firstUniqueDC)) {
|
|
133
|
-
// return Promise.reject(Error('If no opts provided, credentials should be of type UniqueDigitalCredential'))
|
|
134
|
-
// }
|
|
135
|
-
//
|
|
136
|
-
// idOpts = isOID4VCIssuerIdentifier(firstUniqueDC.digitalCredential.kmsKeyRef)
|
|
137
|
-
// ? await this.session.context.agent.identifierManagedGetByIssuer({
|
|
138
|
-
// identifier: firstUniqueDC.digitalCredential.kmsKeyRef,
|
|
139
|
-
// })
|
|
140
|
-
// : await this.session.context.agent.identifierManagedGetByKid({
|
|
141
|
-
// identifier: firstUniqueDC.digitalCredential.kmsKeyRef,
|
|
142
|
-
// kmsKeyRef: firstUniqueDC.digitalCredential.kmsKeyRef,
|
|
143
|
-
// })
|
|
144
|
-
//
|
|
145
|
-
// /*
|
|
146
|
-
// const holder = CredentialMapper.isSdJwtDecodedCredential(firstVC)
|
|
147
|
-
// ? firstVC.decodedPayload.cnf?.jwk
|
|
148
|
-
// ? //TODO SDK-19: convert the JWK to hex and search for the appropriate key and associated DID
|
|
149
|
-
// //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
|
|
150
|
-
// `did:jwk:${encodeJoseBlob(firstVC.decodedPayload.cnf?.jwk)}#0`
|
|
151
|
-
// : firstVC.decodedPayload.sub
|
|
152
|
-
// : Array.isArray(firstVC.credentialSubject)
|
|
153
|
-
// ? firstVC.credentialSubject[0].id
|
|
154
|
-
// : firstVC.credentialSubject.id
|
|
155
|
-
// if (holder) {
|
|
156
|
-
// idOpts = { identifier: holder }
|
|
157
|
-
// }
|
|
158
|
-
// */
|
|
159
|
-
// } else if (opts?.holder) {
|
|
160
|
-
// idOpts = { identifier: opts.holder }
|
|
161
|
-
// }
|
|
162
|
-
// }
|
|
163
|
-
//
|
|
164
|
-
// // We are making sure to filter, in case the user submitted all verifiableCredentials in the wallet/agent. We also make sure to get original formats back
|
|
165
|
-
// const vcs = forceNoCredentialsInVP
|
|
166
|
-
// ? selectedVerifiableCredentials
|
|
167
|
-
// : opts?.applyFilter
|
|
168
|
-
// ? await this.filterCredentials(credentialRole, selectedVerifiableCredentials.dcqlQuery, {
|
|
169
|
-
// restrictToFormats: opts?.restrictToFormats,
|
|
170
|
-
// restrictToDIDMethods: opts?.restrictToDIDMethods,
|
|
171
|
-
// filterOpts: {
|
|
172
|
-
// verifiableCredentials: selectedVerifiableCredentials.credentials,
|
|
173
|
-
// },
|
|
174
|
-
// })
|
|
175
|
-
// : {
|
|
176
|
-
// definition: selectedVerifiableCredentials.dcqlQuery,
|
|
177
|
-
// credentials: selectedVerifiableCredentials.credentials,
|
|
178
|
-
// }
|
|
179
|
-
//
|
|
180
|
-
// if (!idOpts) {
|
|
181
|
-
// return Promise.reject(Error(`No identifier options present at this point`))
|
|
182
|
-
// }
|
|
183
|
-
//
|
|
184
|
-
// // const signCallback = await createOID4VPPresentationSignCallback({
|
|
185
|
-
// // presentationSignCallback: this.session.options.presentationSignCallback,
|
|
186
|
-
// // idOpts,
|
|
187
|
-
// // context: this.session.context,
|
|
188
|
-
// // domain: proofOptions.domain,
|
|
189
|
-
// // challenge: proofOptions.challenge,
|
|
190
|
-
// // format: opts?.restrictToFormats ?? selectedVerifiableCredentials.dcqlQuery.dcqlQuery.format,
|
|
191
|
-
// // skipDidResolution: opts?.skipDidResolution ?? false,
|
|
192
|
-
// // })
|
|
193
|
-
// const identifier: ManagedIdentifierResult = await this.session.context.agent.identifierManagedGet(idOpts)
|
|
194
|
-
// const verifiableCredentials = vcs.credentials.map((credential) =>
|
|
195
|
-
// typeof credential === 'object' && 'digitalCredential' in credential ? credential.originalVerifiableCredential! : credential,
|
|
196
|
-
// )
|
|
197
|
-
// // const presentationResult = await this.getPresentationExchange({
|
|
198
|
-
// // verifiableCredentials: verifiableCredentials,
|
|
199
|
-
// // allIdentifiers: this.allIdentifiers,
|
|
200
|
-
// // hasher: opts?.hasher,
|
|
201
|
-
// // }).createVerifiablePresentation(vcs.dcqlQuery.dcqlQuery, verifiableCredentials, signCallback, {
|
|
202
|
-
// // proofOptions,
|
|
203
|
-
// // // fixme: Update to newer siop-vp to not require dids here. But when Veramo is creating the VP it's still looking at this field to pass into didManagerGet
|
|
204
|
-
// // ...(identifier && isManagedIdentifierDidResult(identifier) && { holderDID: identifier.did }),
|
|
205
|
-
// // })
|
|
206
|
-
//
|
|
207
|
-
// const verifiablePresentations = presentationResult.verifiablePresentations.map((verifiablePresentation) =>
|
|
208
|
-
// typeof verifiablePresentation !== 'string' &&
|
|
209
|
-
// 'proof' in verifiablePresentation &&
|
|
210
|
-
// 'jwt' in verifiablePresentation.proof &&
|
|
211
|
-
// verifiablePresentation.proof.jwt
|
|
212
|
-
// ? verifiablePresentation.proof.jwt
|
|
213
|
-
// : verifiablePresentation,
|
|
214
|
-
// )
|
|
215
|
-
//
|
|
216
|
-
// return {
|
|
217
|
-
// ...presentationResult,
|
|
218
|
-
// verifiablePresentations,
|
|
219
|
-
// verifiableCredentials: verifiableCredentials,
|
|
220
|
-
// dcqlQuery: selectedVerifiableCredentials.dcqlQuery,
|
|
221
|
-
// idOpts,
|
|
222
|
-
// }
|
|
223
|
-
// }
|
|
87
|
+
// public async createVerifiablePresentation(
|
|
88
|
+
// credentialRole: CredentialRole,
|
|
89
|
+
// selectedVerifiableCredentials: VerifiableCredentialsWithDefinition,
|
|
90
|
+
// opts?: {
|
|
91
|
+
// forceNoCredentialsInVP?: boolean // Allow to create a VP without credentials, like EBSI is using it. Defaults to false
|
|
92
|
+
// restrictToFormats?: Format
|
|
93
|
+
// restrictToDIDMethods?: string[]
|
|
94
|
+
// proofOpts?: ProofOptions
|
|
95
|
+
// idOpts?: ManagedIdentifierOptsOrResult
|
|
96
|
+
// skipDidResolution?: boolean
|
|
97
|
+
// holder?: string
|
|
98
|
+
// subjectIsHolder?: boolean
|
|
99
|
+
// applyFilter?: boolean
|
|
100
|
+
// hasher?: HasherSync
|
|
101
|
+
// },
|
|
102
|
+
// ): Promise<VerifiablePresentationWithDefinition> {
|
|
103
|
+
// const { subjectIsHolder, holder, forceNoCredentialsInVP = false } = { ...opts }
|
|
104
|
+
// if (subjectIsHolder && holder) {
|
|
105
|
+
// throw Error('Cannot both have subject is holder and a holderDID value at the same time (programming error)')
|
|
106
|
+
// }
|
|
107
|
+
// if (forceNoCredentialsInVP) {
|
|
108
|
+
// selectedVerifiableCredentials.credentials = []
|
|
109
|
+
// } else if (!selectedVerifiableCredentials?.credentials || selectedVerifiableCredentials.credentials.length === 0) {
|
|
110
|
+
// throw Error('No verifiable verifiableCredentials provided for presentation definition')
|
|
111
|
+
// }
|
|
112
|
+
//
|
|
113
|
+
// // const proofOptions: ProofOptions = {
|
|
114
|
+
// // ...opts?.proofOpts,
|
|
115
|
+
// // challenge: opts?.proofOpts?.nonce ?? opts?.proofOpts?.challenge ?? this.session.nonce,
|
|
116
|
+
// // domain: opts?.proofOpts?.domain ?? (await this.session.getRedirectUri()),
|
|
117
|
+
// // }
|
|
118
|
+
//
|
|
119
|
+
// let idOpts = opts?.idOpts
|
|
120
|
+
// if (!idOpts) {
|
|
121
|
+
// if (opts?.subjectIsHolder) {
|
|
122
|
+
// if (forceNoCredentialsInVP) {
|
|
123
|
+
// return Promise.reject(
|
|
124
|
+
// Error(
|
|
125
|
+
// `Cannot have subject is holder, when force no credentials is being used, as we could never determine the holder then. Please provide holderDID`,
|
|
126
|
+
// ),
|
|
127
|
+
// )
|
|
128
|
+
// }
|
|
129
|
+
// const firstUniqueDC = selectedVerifiableCredentials.credentials[0]
|
|
130
|
+
// // const firstVC = firstUniqueDC.uniformVerifiableCredential!
|
|
131
|
+
// if (typeof firstUniqueDC !== 'object' || !('digitalCredential' in firstUniqueDC)) {
|
|
132
|
+
// return Promise.reject(Error('If no opts provided, credentials should be of type UniqueDigitalCredential'))
|
|
133
|
+
// }
|
|
134
|
+
//
|
|
135
|
+
// idOpts = isOID4VCIssuerIdentifier(firstUniqueDC.digitalCredential.kmsKeyRef)
|
|
136
|
+
// ? await this.session.context.agent.identifierManagedGetByIssuer({
|
|
137
|
+
// identifier: firstUniqueDC.digitalCredential.kmsKeyRef,
|
|
138
|
+
// })
|
|
139
|
+
// : await this.session.context.agent.identifierManagedGetByKid({
|
|
140
|
+
// identifier: firstUniqueDC.digitalCredential.kmsKeyRef,
|
|
141
|
+
// kmsKeyRef: firstUniqueDC.digitalCredential.kmsKeyRef,
|
|
142
|
+
// })
|
|
143
|
+
//
|
|
144
|
+
// /*
|
|
145
|
+
// const holder = CredentialMapper.isSdJwtDecodedCredential(firstVC)
|
|
146
|
+
// ? firstVC.decodedPayload.cnf?.jwk
|
|
147
|
+
// ? //TODO SDK-19: convert the JWK to hex and search for the appropriate key and associated DID
|
|
148
|
+
// //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
|
|
149
|
+
// `did:jwk:${encodeJoseBlob(firstVC.decodedPayload.cnf?.jwk)}#0`
|
|
150
|
+
// : firstVC.decodedPayload.sub
|
|
151
|
+
// : Array.isArray(firstVC.credentialSubject)
|
|
152
|
+
// ? firstVC.credentialSubject[0].id
|
|
153
|
+
// : firstVC.credentialSubject.id
|
|
154
|
+
// if (holder) {
|
|
155
|
+
// idOpts = { identifier: holder }
|
|
156
|
+
// }
|
|
157
|
+
// */
|
|
158
|
+
// } else if (opts?.holder) {
|
|
159
|
+
// idOpts = { identifier: opts.holder }
|
|
160
|
+
// }
|
|
161
|
+
// }
|
|
162
|
+
//
|
|
163
|
+
// // We are making sure to filter, in case the user submitted all verifiableCredentials in the wallet/agent. We also make sure to get original formats back
|
|
164
|
+
// const vcs = forceNoCredentialsInVP
|
|
165
|
+
// ? selectedVerifiableCredentials
|
|
166
|
+
// : opts?.applyFilter
|
|
167
|
+
// ? await this.filterCredentials(credentialRole, selectedVerifiableCredentials.dcqlQuery, {
|
|
168
|
+
// restrictToFormats: opts?.restrictToFormats,
|
|
169
|
+
// restrictToDIDMethods: opts?.restrictToDIDMethods,
|
|
170
|
+
// filterOpts: {
|
|
171
|
+
// verifiableCredentials: selectedVerifiableCredentials.credentials,
|
|
172
|
+
// },
|
|
173
|
+
// })
|
|
174
|
+
// : {
|
|
175
|
+
// definition: selectedVerifiableCredentials.dcqlQuery,
|
|
176
|
+
// credentials: selectedVerifiableCredentials.credentials,
|
|
177
|
+
// }
|
|
178
|
+
//
|
|
179
|
+
// if (!idOpts) {
|
|
180
|
+
// return Promise.reject(Error(`No identifier options present at this point`))
|
|
181
|
+
// }
|
|
182
|
+
//
|
|
183
|
+
// // const signCallback = await createOID4VPPresentationSignCallback({
|
|
184
|
+
// // presentationSignCallback: this.session.options.presentationSignCallback,
|
|
185
|
+
// // idOpts,
|
|
186
|
+
// // context: this.session.context,
|
|
187
|
+
// // domain: proofOptions.domain,
|
|
188
|
+
// // challenge: proofOptions.challenge,
|
|
189
|
+
// // format: opts?.restrictToFormats ?? selectedVerifiableCredentials.dcqlQuery.dcqlQuery.format,
|
|
190
|
+
// // skipDidResolution: opts?.skipDidResolution ?? false,
|
|
191
|
+
// // })
|
|
192
|
+
// const identifier: ManagedIdentifierResult = await this.session.context.agent.identifierManagedGet(idOpts)
|
|
193
|
+
// const verifiableCredentials = vcs.credentials.map((credential) =>
|
|
194
|
+
// typeof credential === 'object' && 'digitalCredential' in credential ? credential.originalVerifiableCredential! : credential,
|
|
195
|
+
// )
|
|
196
|
+
// // const presentationResult = await this.getPresentationExchange({
|
|
197
|
+
// // verifiableCredentials: verifiableCredentials,
|
|
198
|
+
// // allIdentifiers: this.allIdentifiers,
|
|
199
|
+
// // hasher: opts?.hasher,
|
|
200
|
+
// // }).createVerifiablePresentation(vcs.dcqlQuery.dcqlQuery, verifiableCredentials, signCallback, {
|
|
201
|
+
// // proofOptions,
|
|
202
|
+
// // // fixme: Update to newer siop-vp to not require dids here. But when Veramo is creating the VP it's still looking at this field to pass into didManagerGet
|
|
203
|
+
// // ...(identifier && isManagedIdentifierDidResult(identifier) && { holderDID: identifier.did }),
|
|
204
|
+
// // })
|
|
205
|
+
//
|
|
206
|
+
// const verifiablePresentations = presentationResult.verifiablePresentations.map((verifiablePresentation) =>
|
|
207
|
+
// typeof verifiablePresentation !== 'string' &&
|
|
208
|
+
// 'proof' in verifiablePresentation &&
|
|
209
|
+
// 'jwt' in verifiablePresentation.proof &&
|
|
210
|
+
// verifiablePresentation.proof.jwt
|
|
211
|
+
// ? verifiablePresentation.proof.jwt
|
|
212
|
+
// : verifiablePresentation,
|
|
213
|
+
// )
|
|
214
|
+
//
|
|
215
|
+
// return {
|
|
216
|
+
// ...presentationResult,
|
|
217
|
+
// verifiablePresentations,
|
|
218
|
+
// verifiableCredentials: verifiableCredentials,
|
|
219
|
+
// dcqlQuery: selectedVerifiableCredentials.dcqlQuery,
|
|
220
|
+
// idOpts,
|
|
221
|
+
// }
|
|
222
|
+
// }
|
|
224
223
|
|
|
225
224
|
// public async filterCredentialsAgainstAllDefinitions(
|
|
226
225
|
// credentialRole: CredentialRole,
|
|
@@ -284,50 +283,50 @@ export class OID4VP {
|
|
|
284
283
|
// }
|
|
285
284
|
// }
|
|
286
285
|
|
|
287
|
-
// public async filterCredentialsWithSelectionStatus(
|
|
288
|
-
// credentialRole: CredentialRole,
|
|
289
|
-
// presentationDefinition: PresentationDefinitionWithLocation,
|
|
290
|
-
// opts?: {
|
|
291
|
-
// filterOpts?: { verifiableCredentials?: OriginalVerifiableCredential[]; filter?: FindDigitalCredentialArgs }
|
|
292
|
-
// holderDIDs?: string[]
|
|
293
|
-
// restrictToFormats?: Format
|
|
294
|
-
// restrictToDIDMethods?: string[]
|
|
295
|
-
// },
|
|
296
|
-
// ): Promise<SelectResults> {
|
|
297
|
-
// const selectionResults: SelectResults = await this.getPresentationExchange({
|
|
298
|
-
// verifiableCredentials: await this.getCredentials(credentialRole, opts?.filterOpts),
|
|
299
|
-
// }).selectVerifiableCredentialsForSubmission(presentationDefinition.definition, opts)
|
|
300
|
-
// if (selectionResults.errors && selectionResults.errors.length > 0) {
|
|
301
|
-
// throw Error(JSON.stringify(selectionResults.errors))
|
|
302
|
-
// } else if (selectionResults.areRequiredCredentialsPresent === Status.ERROR) {
|
|
303
|
-
// throw Error(`Not all required credentials are available to satisfy the relying party's request`)
|
|
304
|
-
// }
|
|
305
|
-
//
|
|
306
|
-
// const matches: SubmissionRequirementMatch[] | undefined = selectionResults.matches
|
|
307
|
-
// if (!matches || matches.length === 0 || !selectionResults.verifiableCredential || selectionResults.verifiableCredential.length === 0) {
|
|
308
|
-
// throw Error(JSON.stringify(selectionResults.errors))
|
|
309
|
-
// }
|
|
310
|
-
// return selectionResults
|
|
311
|
-
// }
|
|
312
|
-
//
|
|
313
|
-
// private async getCredentials(
|
|
314
|
-
// credentialRole: CredentialRole,
|
|
315
|
-
// filterOpts?: {
|
|
316
|
-
// verifiableCredentials?: OriginalVerifiableCredential[]
|
|
317
|
-
// filter?: FindDigitalCredentialArgs
|
|
318
|
-
// },
|
|
319
|
-
// ): Promise<OriginalVerifiableCredential[]> {
|
|
320
|
-
// if (filterOpts?.verifiableCredentials && filterOpts.verifiableCredentials.length > 0) {
|
|
321
|
-
// return filterOpts.verifiableCredentials
|
|
322
|
-
// }
|
|
323
|
-
//
|
|
324
|
-
// const filter = verifiableCredentialForRoleFilter(credentialRole, filterOpts?.filter)
|
|
325
|
-
// const uniqueCredentials = await this.session.context.agent.crsGetUniqueCredentials({ filter })
|
|
326
|
-
// return uniqueCredentials.map((uniqueVC: UniqueDigitalCredential) => {
|
|
327
|
-
// const vc = uniqueVC.uniformVerifiableCredential!
|
|
328
|
-
// const proof = Array.isArray(vc.proof) ? vc.proof : [vc.proof]
|
|
329
|
-
// const jwtProof = proof.find((p: IProof) => p?.type === DEFAULT_JWT_PROOF_TYPE)
|
|
330
|
-
// return jwtProof ? (jwtProof.jwt as CompactJWT) : vc
|
|
331
|
-
// })
|
|
332
|
-
// }
|
|
286
|
+
// public async filterCredentialsWithSelectionStatus(
|
|
287
|
+
// credentialRole: CredentialRole,
|
|
288
|
+
// presentationDefinition: PresentationDefinitionWithLocation,
|
|
289
|
+
// opts?: {
|
|
290
|
+
// filterOpts?: { verifiableCredentials?: OriginalVerifiableCredential[]; filter?: FindDigitalCredentialArgs }
|
|
291
|
+
// holderDIDs?: string[]
|
|
292
|
+
// restrictToFormats?: Format
|
|
293
|
+
// restrictToDIDMethods?: string[]
|
|
294
|
+
// },
|
|
295
|
+
// ): Promise<SelectResults> {
|
|
296
|
+
// const selectionResults: SelectResults = await this.getPresentationExchange({
|
|
297
|
+
// verifiableCredentials: await this.getCredentials(credentialRole, opts?.filterOpts),
|
|
298
|
+
// }).selectVerifiableCredentialsForSubmission(presentationDefinition.definition, opts)
|
|
299
|
+
// if (selectionResults.errors && selectionResults.errors.length > 0) {
|
|
300
|
+
// throw Error(JSON.stringify(selectionResults.errors))
|
|
301
|
+
// } else if (selectionResults.areRequiredCredentialsPresent === Status.ERROR) {
|
|
302
|
+
// throw Error(`Not all required credentials are available to satisfy the relying party's request`)
|
|
303
|
+
// }
|
|
304
|
+
//
|
|
305
|
+
// const matches: SubmissionRequirementMatch[] | undefined = selectionResults.matches
|
|
306
|
+
// if (!matches || matches.length === 0 || !selectionResults.verifiableCredential || selectionResults.verifiableCredential.length === 0) {
|
|
307
|
+
// throw Error(JSON.stringify(selectionResults.errors))
|
|
308
|
+
// }
|
|
309
|
+
// return selectionResults
|
|
310
|
+
// }
|
|
311
|
+
//
|
|
312
|
+
// private async getCredentials(
|
|
313
|
+
// credentialRole: CredentialRole,
|
|
314
|
+
// filterOpts?: {
|
|
315
|
+
// verifiableCredentials?: OriginalVerifiableCredential[]
|
|
316
|
+
// filter?: FindDigitalCredentialArgs
|
|
317
|
+
// },
|
|
318
|
+
// ): Promise<OriginalVerifiableCredential[]> {
|
|
319
|
+
// if (filterOpts?.verifiableCredentials && filterOpts.verifiableCredentials.length > 0) {
|
|
320
|
+
// return filterOpts.verifiableCredentials
|
|
321
|
+
// }
|
|
322
|
+
//
|
|
323
|
+
// const filter = verifiableCredentialForRoleFilter(credentialRole, filterOpts?.filter)
|
|
324
|
+
// const uniqueCredentials = await this.session.context.agent.crsGetUniqueCredentials({ filter })
|
|
325
|
+
// return uniqueCredentials.map((uniqueVC: UniqueDigitalCredential) => {
|
|
326
|
+
// const vc = uniqueVC.uniformVerifiableCredential!
|
|
327
|
+
// const proof = Array.isArray(vc.proof) ? vc.proof : [vc.proof]
|
|
328
|
+
// const jwtProof = proof.find((p: IProof) => p?.type === DEFAULT_JWT_PROOF_TYPE)
|
|
329
|
+
// return jwtProof ? (jwtProof.jwt as CompactJWT) : vc
|
|
330
|
+
// })
|
|
331
|
+
// }
|
|
333
332
|
}
|
|
@@ -12,7 +12,7 @@ import { DIDDocument } from '@sphereon/did-uni-client'
|
|
|
12
12
|
import { IIdentifierResolution, ManagedIdentifierOptsOrResult } from '@sphereon/ssi-sdk-ext.identifier-resolution'
|
|
13
13
|
import { IJwtService } from '@sphereon/ssi-sdk-ext.jwt-service'
|
|
14
14
|
import { ICredentialStore } from '@sphereon/ssi-sdk.credential-store'
|
|
15
|
-
import { Party } from '@sphereon/ssi-sdk.data-store'
|
|
15
|
+
import { Party } from '@sphereon/ssi-sdk.data-store-types'
|
|
16
16
|
import { IPDManager } from '@sphereon/ssi-sdk.pd-manager'
|
|
17
17
|
import { ISDJwtPlugin } from '@sphereon/ssi-sdk.sd-jwt'
|
|
18
18
|
import { HasherSync, PresentationSubmission, W3CVerifiablePresentation } from '@sphereon/ssi-types'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { VerifiedAuthorizationRequest } from '@sphereon/did-auth-siop'
|
|
2
2
|
import { ManagedIdentifierOptsOrResult } from '@sphereon/ssi-sdk-ext.identifier-resolution'
|
|
3
|
-
import { DidAuthConfig, Party } from '@sphereon/ssi-sdk.data-store'
|
|
3
|
+
import { DidAuthConfig, Party } from '@sphereon/ssi-sdk.data-store-types'
|
|
4
4
|
import { BaseActionObject, Interpreter, ResolveTypegenMeta, ServiceMap, State, StateMachine, TypegenDisabled } from 'xstate'
|
|
5
5
|
import { ErrorDetails } from '../error'
|
|
6
6
|
import { SelectableCredentialsMap, Siopv2AuthorizationRequestData, Siopv2AuthorizationResponseData } from '../siop-service'
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
PresentationSignCallback,
|
|
3
|
-
RPRegistrationMetadataPayload,
|
|
4
|
-
VerifiedAuthorizationRequest,
|
|
5
|
-
} from '@sphereon/did-auth-siop'
|
|
1
|
+
import { PresentationSignCallback, RPRegistrationMetadataPayload, VerifiedAuthorizationRequest } from '@sphereon/did-auth-siop'
|
|
6
2
|
import { IIdentifierResolution, ManagedIdentifierOptsOrResult } from '@sphereon/ssi-sdk-ext.identifier-resolution'
|
|
7
3
|
import { IContactManager } from '@sphereon/ssi-sdk.contact-manager'
|
|
8
4
|
import { ICredentialStore, UniqueDigitalCredential } from '@sphereon/ssi-sdk.credential-store'
|
|
9
|
-
import { DidAuthConfig, ICredentialLocaleBranding, Identity, Party } from '@sphereon/ssi-sdk.data-store'
|
|
5
|
+
import { DidAuthConfig, ICredentialLocaleBranding, Identity, Party } from '@sphereon/ssi-sdk.data-store-types'
|
|
10
6
|
import { IIssuanceBranding } from '@sphereon/ssi-sdk.issuance-branding'
|
|
7
|
+
import { ISDJwtPlugin } from '@sphereon/ssi-sdk.sd-jwt'
|
|
11
8
|
import { IAgentContext, IDIDManager, IIdentifier, IResolver } from '@veramo/core'
|
|
12
9
|
import { IDidAuthSiopOpAuthenticator } from '../IDidAuthSiopOpAuthenticator'
|
|
13
10
|
import { Siopv2MachineContext, Siopv2MachineInterpreter, Siopv2MachineState } from '../machine'
|
|
@@ -90,5 +87,12 @@ export type OnIdentifierCreatedArgs = {
|
|
|
90
87
|
}
|
|
91
88
|
|
|
92
89
|
export type RequiredContext = IAgentContext<
|
|
93
|
-
IContactManager &
|
|
90
|
+
IContactManager &
|
|
91
|
+
IDidAuthSiopOpAuthenticator &
|
|
92
|
+
IDIDManager &
|
|
93
|
+
IResolver &
|
|
94
|
+
IIdentifierResolution &
|
|
95
|
+
ICredentialStore &
|
|
96
|
+
IIssuanceBranding &
|
|
97
|
+
ISDJwtPlugin
|
|
94
98
|
>
|