@sphereon/ssi-sdk.siopv2-oid4vp-op-auth 0.34.1-feature.SSISDK.78.280 → 0.34.1-feature.SSISDK.82.linkedVP.325
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 +261 -201
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -8
- package/dist/index.d.ts +15 -8
- package/dist/index.js +263 -203
- package/dist/index.js.map +1 -1
- package/package.json +22 -22
- package/src/services/Siopv2MachineService.ts +33 -84
- package/src/session/OID4VP.ts +164 -315
- package/src/session/OpSession.ts +4 -20
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-feature.SSISDK.
|
|
3
|
+
"version": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
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-next.
|
|
30
|
-
"@sphereon/did-auth-siop-adapter": "0.19.1-next.
|
|
31
|
-
"@sphereon/oid4vc-common": "0.19.1-next.
|
|
29
|
+
"@sphereon/did-auth-siop": "0.19.1-next.226",
|
|
30
|
+
"@sphereon/did-auth-siop-adapter": "0.19.1-next.226",
|
|
31
|
+
"@sphereon/oid4vc-common": "0.19.1-next.226",
|
|
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-feature.SSISDK.
|
|
35
|
-
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.34.1-feature.SSISDK.
|
|
36
|
-
"@sphereon/ssi-sdk-ext.jwt-service": "0.34.1-feature.SSISDK.
|
|
37
|
-
"@sphereon/ssi-sdk.contact-manager": "0.34.1-feature.SSISDK.
|
|
38
|
-
"@sphereon/ssi-sdk.core": "0.34.1-feature.SSISDK.
|
|
39
|
-
"@sphereon/ssi-sdk.credential-store": "0.34.1-feature.SSISDK.
|
|
40
|
-
"@sphereon/ssi-sdk.credential-validation": "0.34.1-feature.SSISDK.
|
|
41
|
-
"@sphereon/ssi-sdk.data-store-types": "0.34.1-feature.SSISDK.
|
|
42
|
-
"@sphereon/ssi-sdk.issuance-branding": "0.34.1-feature.SSISDK.
|
|
43
|
-
"@sphereon/ssi-sdk.pd-manager": "0.34.1-feature.SSISDK.
|
|
44
|
-
"@sphereon/ssi-sdk.presentation-exchange": "0.34.1-feature.SSISDK.
|
|
45
|
-
"@sphereon/ssi-sdk.sd-jwt": "0.34.1-feature.SSISDK.
|
|
46
|
-
"@sphereon/ssi-sdk.siopv2-oid4vp-common": "0.34.1-feature.SSISDK.
|
|
47
|
-
"@sphereon/ssi-sdk.xstate-machine-persistence": "0.34.1-feature.SSISDK.
|
|
48
|
-
"@sphereon/ssi-types": "0.34.1-feature.SSISDK.
|
|
34
|
+
"@sphereon/ssi-sdk-ext.did-utils": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
35
|
+
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
36
|
+
"@sphereon/ssi-sdk-ext.jwt-service": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
37
|
+
"@sphereon/ssi-sdk.contact-manager": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
38
|
+
"@sphereon/ssi-sdk.core": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
39
|
+
"@sphereon/ssi-sdk.credential-store": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
40
|
+
"@sphereon/ssi-sdk.credential-validation": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
41
|
+
"@sphereon/ssi-sdk.data-store-types": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
42
|
+
"@sphereon/ssi-sdk.issuance-branding": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
43
|
+
"@sphereon/ssi-sdk.pd-manager": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
44
|
+
"@sphereon/ssi-sdk.presentation-exchange": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
45
|
+
"@sphereon/ssi-sdk.sd-jwt": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
46
|
+
"@sphereon/ssi-sdk.siopv2-oid4vp-common": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
47
|
+
"@sphereon/ssi-sdk.xstate-machine-persistence": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
48
|
+
"@sphereon/ssi-types": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
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-feature.SSISDK.
|
|
63
|
-
"@sphereon/ssi-sdk.agent-config": "0.34.1-feature.SSISDK.
|
|
62
|
+
"@sphereon/ssi-sdk-ext.did-resolver-jwk": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
63
|
+
"@sphereon/ssi-sdk.agent-config": "0.34.1-feature.SSISDK.82.linkedVP.325+9de5d4ff",
|
|
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": "9de5d4ff0d17685351d63a9685ec853f6add2d6c"
|
|
106
106
|
}
|
|
@@ -1,23 +1,13 @@
|
|
|
1
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'
|
|
4
2
|
import { getOrCreatePrimaryIdentifier, SupportedDidMethodEnum } from '@sphereon/ssi-sdk-ext.did-utils'
|
|
5
3
|
import { isOID4VCIssuerIdentifier, ManagedIdentifierOptsOrResult } from '@sphereon/ssi-sdk-ext.identifier-resolution'
|
|
6
4
|
import { encodeJoseBlob } from '@sphereon/ssi-sdk.core'
|
|
7
5
|
import { UniqueDigitalCredential, verifiableCredentialForRoleFilter } from '@sphereon/ssi-sdk.credential-store'
|
|
8
6
|
import { ConnectionType } from '@sphereon/ssi-sdk.data-store-types'
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
CredentialMapper,
|
|
12
|
-
CredentialRole,
|
|
13
|
-
HasherSync,
|
|
14
|
-
Loggers,
|
|
15
|
-
OriginalVerifiableCredential,
|
|
16
|
-
SdJwtDecodedVerifiableCredential,
|
|
17
|
-
} from '@sphereon/ssi-types'
|
|
7
|
+
import { CredentialMapper, CredentialRole, HasherSync, Loggers, OriginalVerifiableCredential } from '@sphereon/ssi-types'
|
|
18
8
|
import { IAgentContext, IDIDManager } from '@veramo/core'
|
|
19
9
|
import { DcqlPresentation, DcqlQuery } from 'dcql'
|
|
20
|
-
import { OpSession } from '../session'
|
|
10
|
+
import { createVerifiablePresentationForFormat, OpSession, PresentationBuilderContext } from '../session'
|
|
21
11
|
import { LOGGER_NAMESPACE, RequiredContext, SelectableCredential, SelectableCredentialsMap, Siopv2HolderEvent } from '../types'
|
|
22
12
|
import { convertToDcqlCredentials } from '../utils/dcql'
|
|
23
13
|
|
|
@@ -81,15 +71,18 @@ export const siopSendAuthorizationResponse = async (
|
|
|
81
71
|
let identifier: ManagedIdentifierOptsOrResult
|
|
82
72
|
const digitalCredential = firstUniqueDC.digitalCredential
|
|
83
73
|
const firstVC = firstUniqueDC.uniformVerifiableCredential
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
74
|
+
|
|
75
|
+
// Determine holder DID for identifier resolution
|
|
76
|
+
let holder: string | undefined
|
|
77
|
+
if (CredentialMapper.isSdJwtDecodedCredential(firstVC)) {
|
|
78
|
+
// TODO SDK-19: convert the JWK to hex and search for the appropriate key and associated DID
|
|
79
|
+
// doesn't apply to did:jwk only, as you can represent any DID key as a
|
|
80
|
+
holder = firstVC.decodedPayload.cnf?.jwk ? `did:jwk:${encodeJoseBlob(firstVC.decodedPayload.cnf?.jwk)}#0` : firstVC.decodedPayload.sub
|
|
81
|
+
} else {
|
|
82
|
+
holder = Array.isArray(firstVC.credentialSubject) ? firstVC.credentialSubject[0].id : firstVC.credentialSubject.id
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Resolve identifier
|
|
93
86
|
if (!digitalCredential.kmsKeyRef) {
|
|
94
87
|
// In case the store does not have the kmsKeyRef lets search for the holder
|
|
95
88
|
|
|
@@ -132,39 +125,34 @@ export const siopSendAuthorizationResponse = async (
|
|
|
132
125
|
return Promise.reject(Error('Credentials do not match required query request'))
|
|
133
126
|
}
|
|
134
127
|
|
|
128
|
+
// Build presentation context for format-aware VP creation
|
|
129
|
+
const presentationContext: PresentationBuilderContext = {
|
|
130
|
+
nonce: request.requestObject?.getPayload()?.nonce ?? session.nonce,
|
|
131
|
+
audience: domain,
|
|
132
|
+
agent: context.agent,
|
|
133
|
+
clockSkew: CLOCK_SKEW,
|
|
134
|
+
hasher: args.hasher,
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Build DCQL presentation with format-aware VPs
|
|
135
138
|
const presentation: DcqlPresentation.Output = {}
|
|
136
139
|
const uniqueCredentials = Array.from(dcqlCredentialsWithCredentials.values())
|
|
137
140
|
for (const [key, value] of Object.entries(queryResult.credential_matches)) {
|
|
138
141
|
if (value.success) {
|
|
139
142
|
const matchedCredentials = value.valid_credentials.map((cred) => uniqueCredentials[cred.input_credential_index])
|
|
140
|
-
const vc = matchedCredentials[0] // taking the first match for now
|
|
143
|
+
const vc = matchedCredentials[0] // taking the first match for now
|
|
144
|
+
|
|
141
145
|
if (!vc) {
|
|
142
146
|
continue
|
|
143
147
|
}
|
|
144
|
-
const originalVc = retrieveEncodedCredential(vc as UniqueDigitalCredential) // TODO this is not nice // also always a UniqueDigitalCredential
|
|
145
|
-
if (!originalVc) {
|
|
146
|
-
continue
|
|
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
148
|
|
|
166
|
-
|
|
167
|
-
|
|
149
|
+
try {
|
|
150
|
+
// Use format-aware presentation builder
|
|
151
|
+
const vp = await createVerifiablePresentationForFormat(vc, identifier, presentationContext)
|
|
152
|
+
presentation[key] = vp as any
|
|
153
|
+
} catch (error) {
|
|
154
|
+
logger.error(`Failed to create VP for credential ${key}:`, error)
|
|
155
|
+
throw error
|
|
168
156
|
}
|
|
169
157
|
}
|
|
170
158
|
}
|
|
@@ -182,15 +170,6 @@ export const siopSendAuthorizationResponse = async (
|
|
|
182
170
|
return response
|
|
183
171
|
}
|
|
184
172
|
|
|
185
|
-
const retrieveEncodedCredential = (credential: UniqueDigitalCredential): OriginalVerifiableCredential | undefined => {
|
|
186
|
-
return credential.originalVerifiableCredential !== undefined &&
|
|
187
|
-
credential.originalVerifiableCredential !== null &&
|
|
188
|
-
(credential?.originalVerifiableCredential as SdJwtDecodedVerifiableCredential)?.compactSdJwtVc !== undefined &&
|
|
189
|
-
(credential?.originalVerifiableCredential as SdJwtDecodedVerifiableCredential)?.compactSdJwtVc !== null
|
|
190
|
-
? (credential.originalVerifiableCredential as SdJwtDecodedVerifiableCredential).compactSdJwtVc
|
|
191
|
-
: credential.originalVerifiableCredential
|
|
192
|
-
}
|
|
193
|
-
|
|
194
173
|
export const getSelectableCredentials = async (dcqlQuery: DcqlQuery, context: RequiredContext): Promise<SelectableCredentialsMap> => {
|
|
195
174
|
const agentContext = { ...context, agent: context.agent }
|
|
196
175
|
const { agent } = agentContext
|
|
@@ -246,33 +225,3 @@ export const translateCorrelationIdToName = async (correlationId: string, contex
|
|
|
246
225
|
|
|
247
226
|
return contacts[0].contact.displayName
|
|
248
227
|
}
|
|
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
|
-
}
|