@sphereon/ssi-sdk.siopv2-oid4vp-op-auth 0.34.1-fix.80 → 0.34.1-next.278
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 +84 -44
- 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 +68 -28
- package/dist/index.js.map +1 -1
- package/package.json +22 -22
- package/src/agent/DidAuthSiopOpAuthenticator.ts +5 -22
- package/src/machine/Siopv2Machine.ts +1 -1
- package/src/services/Siopv2MachineService.ts +128 -98
- package/src/session/OID4VP.ts +183 -184
- package/src/session/functions.ts +1 -8
- 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/src/utils/CredentialUtils.ts +1 -1
- package/src/utils/dcql.ts +1 -0
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-
|
|
3
|
+
"version": "0.34.1-next.278+0eacb25b",
|
|
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-
|
|
30
|
-
"@sphereon/did-auth-siop-adapter": "0.19.1-
|
|
31
|
-
"@sphereon/oid4vc-common": "0.19.1-
|
|
29
|
+
"@sphereon/did-auth-siop": "0.19.1-next.220",
|
|
30
|
+
"@sphereon/did-auth-siop-adapter": "0.19.1-next.220",
|
|
31
|
+
"@sphereon/oid4vc-common": "0.19.1-next.220",
|
|
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-
|
|
35
|
-
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.34.1-
|
|
36
|
-
"@sphereon/ssi-sdk-ext.jwt-service": "0.34.1-
|
|
37
|
-
"@sphereon/ssi-sdk.contact-manager": "0.34.1-
|
|
38
|
-
"@sphereon/ssi-sdk.core": "0.34.1-
|
|
39
|
-
"@sphereon/ssi-sdk.credential-store": "0.34.1-
|
|
40
|
-
"@sphereon/ssi-sdk.credential-validation": "0.34.1-
|
|
41
|
-
"@sphereon/ssi-sdk.data-store": "0.34.1-
|
|
42
|
-
"@sphereon/ssi-sdk.issuance-branding": "0.34.1-
|
|
43
|
-
"@sphereon/ssi-sdk.pd-manager": "0.34.1-
|
|
44
|
-
"@sphereon/ssi-sdk.presentation-exchange": "0.34.1-
|
|
45
|
-
"@sphereon/ssi-sdk.sd-jwt": "0.34.1-
|
|
46
|
-
"@sphereon/ssi-sdk.siopv2-oid4vp-common": "0.34.1-
|
|
47
|
-
"@sphereon/ssi-sdk.xstate-machine-persistence": "0.34.1-
|
|
48
|
-
"@sphereon/ssi-types": "0.34.1-
|
|
34
|
+
"@sphereon/ssi-sdk-ext.did-utils": "0.34.1-next.278+0eacb25b",
|
|
35
|
+
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.34.1-next.278+0eacb25b",
|
|
36
|
+
"@sphereon/ssi-sdk-ext.jwt-service": "0.34.1-next.278+0eacb25b",
|
|
37
|
+
"@sphereon/ssi-sdk.contact-manager": "0.34.1-next.278+0eacb25b",
|
|
38
|
+
"@sphereon/ssi-sdk.core": "0.34.1-next.278+0eacb25b",
|
|
39
|
+
"@sphereon/ssi-sdk.credential-store": "0.34.1-next.278+0eacb25b",
|
|
40
|
+
"@sphereon/ssi-sdk.credential-validation": "0.34.1-next.278+0eacb25b",
|
|
41
|
+
"@sphereon/ssi-sdk.data-store-types": "0.34.1-next.278+0eacb25b",
|
|
42
|
+
"@sphereon/ssi-sdk.issuance-branding": "0.34.1-next.278+0eacb25b",
|
|
43
|
+
"@sphereon/ssi-sdk.pd-manager": "0.34.1-next.278+0eacb25b",
|
|
44
|
+
"@sphereon/ssi-sdk.presentation-exchange": "0.34.1-next.278+0eacb25b",
|
|
45
|
+
"@sphereon/ssi-sdk.sd-jwt": "0.34.1-next.278+0eacb25b",
|
|
46
|
+
"@sphereon/ssi-sdk.siopv2-oid4vp-common": "0.34.1-next.278+0eacb25b",
|
|
47
|
+
"@sphereon/ssi-sdk.xstate-machine-persistence": "0.34.1-next.278+0eacb25b",
|
|
48
|
+
"@sphereon/ssi-types": "0.34.1-next.278+0eacb25b",
|
|
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-
|
|
63
|
-
"@sphereon/ssi-sdk.agent-config": "0.34.1-
|
|
62
|
+
"@sphereon/ssi-sdk-ext.did-resolver-jwk": "0.34.1-next.278+0eacb25b",
|
|
63
|
+
"@sphereon/ssi-sdk.agent-config": "0.34.1-next.278+0eacb25b",
|
|
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": "0eacb25b6e38cef88d04d696d84e3c2ebcf89ede"
|
|
106
106
|
}
|
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
VerifiedAuthorizationRequest } from '@sphereon/did-auth-siop'
|
|
5
|
-
import {
|
|
6
|
-
ConnectionType,
|
|
7
|
-
CorrelationIdentifierType,
|
|
8
|
-
CredentialRole,
|
|
9
|
-
Identity,
|
|
10
|
-
IdentityOrigin,
|
|
11
|
-
NonPersistedIdentity,
|
|
12
|
-
Party,
|
|
13
|
-
} from '@sphereon/ssi-sdk.data-store'
|
|
14
|
-
import { HasherSync, Loggers } from '@sphereon/ssi-types'
|
|
1
|
+
import { decodeUriAsJson, PresentationSignCallback, VerifiedAuthorizationRequest } from '@sphereon/did-auth-siop'
|
|
2
|
+
import { ConnectionType, CorrelationIdentifierType, Identity, IdentityOrigin, NonPersistedIdentity, Party } from '@sphereon/ssi-sdk.data-store-types'
|
|
3
|
+
import { HasherSync, Loggers, CredentialRole } from '@sphereon/ssi-types'
|
|
15
4
|
import { IAgentPlugin } from '@veramo/core'
|
|
16
5
|
import { v4 as uuidv4 } from 'uuid'
|
|
17
6
|
import { OpSession } from '../session'
|
|
@@ -92,13 +81,7 @@ export class DidAuthSiopOpAuthenticator implements IAgentPlugin {
|
|
|
92
81
|
private readonly hasher?: HasherSync
|
|
93
82
|
|
|
94
83
|
constructor(options?: DidAuthSiopOpAuthenticatorOptions) {
|
|
95
|
-
const {
|
|
96
|
-
onContactIdentityCreated,
|
|
97
|
-
onIdentifierCreated,
|
|
98
|
-
hasher,
|
|
99
|
-
customApprovals = {},
|
|
100
|
-
presentationSignCallback
|
|
101
|
-
} = { ...options }
|
|
84
|
+
const { onContactIdentityCreated, onIdentifierCreated, hasher, customApprovals = {}, presentationSignCallback } = { ...options }
|
|
102
85
|
|
|
103
86
|
this.hasher = hasher
|
|
104
87
|
this.onContactIdentityCreated = onContactIdentityCreated
|
|
@@ -231,7 +214,7 @@ export class DidAuthSiopOpAuthenticator implements IAgentPlugin {
|
|
|
231
214
|
(args.url.includes('request_uri')
|
|
232
215
|
? decodeURIComponent(args.url.split('?request_uri=')[1].trim())
|
|
233
216
|
: (verifiedAuthorizationRequest.issuer ?? verifiedAuthorizationRequest.registrationMetadataPayload?.client_id))
|
|
234
|
-
const uri: URL | undefined = url
|
|
217
|
+
const uri: URL | undefined = url?.includes('://') ? new URL(url) : undefined
|
|
235
218
|
const correlationId: string = uri?.hostname ?? (await this.determineCorrelationId(uri, verifiedAuthorizationRequest, clientName, context))
|
|
236
219
|
const clientId: string | undefined = verifiedAuthorizationRequest.authorizationRequest.getMergedProperty<string>('client_id')
|
|
237
220
|
|
|
@@ -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,34 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from '@sphereon/did-auth-siop'
|
|
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
|
+
import { getOrCreatePrimaryIdentifier, SupportedDidMethodEnum } from '@sphereon/ssi-sdk-ext.did-utils'
|
|
6
5
|
import { isOID4VCIssuerIdentifier, ManagedIdentifierOptsOrResult } from '@sphereon/ssi-sdk-ext.identifier-resolution'
|
|
6
|
+
import { encodeJoseBlob } from '@sphereon/ssi-sdk.core'
|
|
7
7
|
import { UniqueDigitalCredential, verifiableCredentialForRoleFilter } from '@sphereon/ssi-sdk.credential-store'
|
|
8
|
-
import { ConnectionType
|
|
8
|
+
import { ConnectionType } from '@sphereon/ssi-sdk.data-store-types'
|
|
9
|
+
import { defaultGenerateDigest } from '@sphereon/ssi-sdk.sd-jwt'
|
|
9
10
|
import {
|
|
10
11
|
CredentialMapper,
|
|
12
|
+
CredentialRole,
|
|
11
13
|
HasherSync,
|
|
12
14
|
Loggers,
|
|
13
15
|
OriginalVerifiableCredential,
|
|
14
|
-
SdJwtDecodedVerifiableCredential
|
|
16
|
+
SdJwtDecodedVerifiableCredential,
|
|
15
17
|
} from '@sphereon/ssi-types'
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
LOGGER_NAMESPACE,
|
|
19
|
-
RequiredContext,
|
|
20
|
-
SelectableCredential,
|
|
21
|
-
SelectableCredentialsMap,
|
|
22
|
-
Siopv2HolderEvent
|
|
23
|
-
} from '../types'
|
|
24
|
-
import { encodeJoseBlob } from '@sphereon/ssi-sdk.core'
|
|
18
|
+
import { IAgentContext, IDIDManager } from '@veramo/core'
|
|
25
19
|
import { DcqlPresentation, DcqlQuery } from 'dcql'
|
|
20
|
+
import { OpSession } from '../session'
|
|
21
|
+
import { LOGGER_NAMESPACE, RequiredContext, SelectableCredential, SelectableCredentialsMap, Siopv2HolderEvent } from '../types'
|
|
26
22
|
import { convertToDcqlCredentials } from '../utils/dcql'
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
getOrCreatePrimaryIdentifier,
|
|
30
|
-
SupportedDidMethodEnum
|
|
31
|
-
} from '@sphereon/ssi-sdk-ext.did-utils'
|
|
23
|
+
|
|
24
|
+
const CLOCK_SKEW = 120
|
|
32
25
|
|
|
33
26
|
export const logger = Loggers.DEFAULT.get(LOGGER_NAMESPACE)
|
|
34
27
|
|
|
@@ -76,68 +69,62 @@ export const siopSendAuthorizationResponse = async (
|
|
|
76
69
|
logger.debug(`AUD: ${aud}`)
|
|
77
70
|
logger.debug(JSON.stringify(request.authorizationRequest))
|
|
78
71
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
72
|
+
const domain = ((await request.authorizationRequest.getMergedProperty('client_id')) as string) ?? request.issuer ?? 'https://self-issued.me/v2'
|
|
73
|
+
|
|
74
|
+
logger.debug(`NONCE: ${session.nonce}, domain: ${domain}`)
|
|
75
|
+
|
|
76
|
+
const firstUniqueDC = credentials[0]
|
|
77
|
+
if (typeof firstUniqueDC !== 'object' || !('digitalCredential' in firstUniqueDC)) {
|
|
78
|
+
return Promise.reject(Error('SiopMachine only supports UniqueDigitalCredentials for now'))
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let identifier: ManagedIdentifierOptsOrResult
|
|
82
|
+
const digitalCredential = firstUniqueDC.digitalCredential
|
|
83
|
+
const firstVC = firstUniqueDC.uniformVerifiableCredential
|
|
84
|
+
const holder = CredentialMapper.isSdJwtDecodedCredential(firstVC)
|
|
85
|
+
? firstVC.decodedPayload.cnf?.jwk
|
|
86
|
+
? //TODO SDK-19: convert the JWK to hex and search for the appropriate key and associated DID
|
|
87
|
+
//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
|
|
88
|
+
`did:jwk:${encodeJoseBlob(firstVC.decodedPayload.cnf?.jwk)}#0`
|
|
89
|
+
: firstVC.decodedPayload.sub
|
|
90
|
+
: Array.isArray(firstVC.credentialSubject)
|
|
91
|
+
? firstVC.credentialSubject[0].id
|
|
92
|
+
: firstVC.credentialSubject.id
|
|
93
|
+
if (!digitalCredential.kmsKeyRef) {
|
|
94
|
+
// In case the store does not have the kmsKeyRef lets search for the holder
|
|
91
95
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
identifier = await session.context.agent.identifierManagedGet({ identifier: holder })
|
|
112
|
-
} catch (e) {
|
|
113
|
-
logger.debug(`Holder DID not found: ${holder}`)
|
|
114
|
-
throw e
|
|
115
|
-
}
|
|
116
|
-
} else if (isOID4VCIssuerIdentifier(digitalCredential.kmsKeyRef)) {
|
|
117
|
-
identifier = await session.context.agent.identifierManagedGetByOID4VCIssuer({
|
|
118
|
-
identifier: firstUniqueDC.digitalCredential.kmsKeyRef,
|
|
96
|
+
if (!holder) {
|
|
97
|
+
return Promise.reject(`No holder found and no kmsKeyRef in DB. Cannot determine identifier to use`)
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
identifier = await session.context.agent.identifierManagedGet({ identifier: holder })
|
|
101
|
+
} catch (e) {
|
|
102
|
+
logger.debug(`Holder DID not found: ${holder}`)
|
|
103
|
+
throw e
|
|
104
|
+
}
|
|
105
|
+
} else if (isOID4VCIssuerIdentifier(digitalCredential.kmsKeyRef)) {
|
|
106
|
+
identifier = await session.context.agent.identifierManagedGetByOID4VCIssuer({
|
|
107
|
+
identifier: firstUniqueDC.digitalCredential.kmsKeyRef,
|
|
108
|
+
})
|
|
109
|
+
} else {
|
|
110
|
+
switch (digitalCredential.subjectCorrelationType) {
|
|
111
|
+
case 'DID':
|
|
112
|
+
identifier = await session.context.agent.identifierManagedGetByDid({
|
|
113
|
+
identifier: digitalCredential.subjectCorrelationId ?? holder,
|
|
114
|
+
kmsKeyRef: digitalCredential.kmsKeyRef,
|
|
119
115
|
})
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
// Since we are using the kmsKeyRef we will find the KID regardless of the identifier. We set it for later access though
|
|
131
|
-
identifier = await session.context.agent.identifierManagedGetByKid({
|
|
132
|
-
identifier: digitalCredential.subjectCorrelationId ?? holder ?? digitalCredential.kmsKeyRef,
|
|
133
|
-
kmsKeyRef: digitalCredential.kmsKeyRef,
|
|
134
|
-
})
|
|
135
|
-
}
|
|
136
|
-
}
|
|
116
|
+
break
|
|
117
|
+
// TODO other implementations?
|
|
118
|
+
default:
|
|
119
|
+
// Since we are using the kmsKeyRef we will find the KID regardless of the identifier. We set it for later access though
|
|
120
|
+
identifier = await session.context.agent.identifierManagedGetByKid({
|
|
121
|
+
identifier: digitalCredential.subjectCorrelationId ?? holder ?? digitalCredential.kmsKeyRef,
|
|
122
|
+
kmsKeyRef: digitalCredential.kmsKeyRef,
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
}
|
|
137
126
|
|
|
138
|
-
const dcqlCredentialsWithCredentials = new Map(
|
|
139
|
-
credentials.map((vc) => [convertToDcqlCredentials(vc), vc])
|
|
140
|
-
)
|
|
127
|
+
const dcqlCredentialsWithCredentials = new Map(credentials.map((vc) => [convertToDcqlCredentials(vc), vc]))
|
|
141
128
|
|
|
142
129
|
const queryResult = DcqlQuery.query(request.dcqlQuery, Array.from(dcqlCredentialsWithCredentials.keys()))
|
|
143
130
|
|
|
@@ -149,7 +136,7 @@ export const siopSendAuthorizationResponse = async (
|
|
|
149
136
|
const uniqueCredentials = Array.from(dcqlCredentialsWithCredentials.values())
|
|
150
137
|
for (const [key, value] of Object.entries(queryResult.credential_matches)) {
|
|
151
138
|
if (value.success) {
|
|
152
|
-
const matchedCredentials = value.valid_credentials.map(cred => uniqueCredentials[cred.input_credential_index])
|
|
139
|
+
const matchedCredentials = value.valid_credentials.map((cred) => uniqueCredentials[cred.input_credential_index])
|
|
153
140
|
const vc = matchedCredentials[0] // taking the first match for now //uniqueCredentials[value.input_credential_index]
|
|
154
141
|
if (!vc) {
|
|
155
142
|
continue
|
|
@@ -158,23 +145,41 @@ export const siopSendAuthorizationResponse = async (
|
|
|
158
145
|
if (!originalVc) {
|
|
159
146
|
continue
|
|
160
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
|
+
|
|
161
166
|
if (originalVc) {
|
|
162
|
-
presentation[key] =
|
|
167
|
+
presentation[key] = presentationResult.presentation
|
|
163
168
|
}
|
|
164
169
|
}
|
|
165
170
|
}
|
|
166
171
|
|
|
167
172
|
const dcqlPresentation = DcqlPresentation.parse(presentation)
|
|
168
173
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
174
|
+
const response = session.sendAuthorizationResponse({
|
|
175
|
+
responseSignerOpts: identifier,
|
|
176
|
+
dcqlResponse: {
|
|
177
|
+
dcqlPresentation,
|
|
178
|
+
},
|
|
179
|
+
})
|
|
175
180
|
|
|
176
|
-
|
|
177
|
-
|
|
181
|
+
logger.debug(`Response: `, response)
|
|
182
|
+
return response
|
|
178
183
|
}
|
|
179
184
|
|
|
180
185
|
const retrieveEncodedCredential = (credential: UniqueDigitalCredential): OriginalVerifiableCredential | undefined => {
|
|
@@ -186,19 +191,14 @@ const retrieveEncodedCredential = (credential: UniqueDigitalCredential): Origina
|
|
|
186
191
|
: credential.originalVerifiableCredential
|
|
187
192
|
}
|
|
188
193
|
|
|
189
|
-
export const getSelectableCredentials = async (
|
|
190
|
-
dcqlQuery: DcqlQuery,
|
|
191
|
-
context: RequiredContext,
|
|
192
|
-
): Promise<SelectableCredentialsMap> => {
|
|
194
|
+
export const getSelectableCredentials = async (dcqlQuery: DcqlQuery, context: RequiredContext): Promise<SelectableCredentialsMap> => {
|
|
193
195
|
const agentContext = { ...context, agent: context.agent }
|
|
194
196
|
const { agent } = agentContext
|
|
195
197
|
const uniqueVerifiableCredentials = await agent.crsGetUniqueCredentials({
|
|
196
198
|
filter: verifiableCredentialForRoleFilter(CredentialRole.HOLDER),
|
|
197
199
|
})
|
|
198
200
|
const branding = await agent.ibGetCredentialBranding()
|
|
199
|
-
const dcqlCredentialsWithCredentials = new Map(
|
|
200
|
-
uniqueVerifiableCredentials.map((vc) => [convertToDcqlCredentials(vc), vc])
|
|
201
|
-
)
|
|
201
|
+
const dcqlCredentialsWithCredentials = new Map(uniqueVerifiableCredentials.map((vc) => [convertToDcqlCredentials(vc), vc]))
|
|
202
202
|
const queryResult = DcqlQuery.query(dcqlQuery, Array.from(dcqlCredentialsWithCredentials.keys()))
|
|
203
203
|
const uniqueCredentials = Array.from(dcqlCredentialsWithCredentials.values())
|
|
204
204
|
const selectableCredentialsMap: SelectableCredentialsMap = new Map()
|
|
@@ -208,7 +208,7 @@ export const getSelectableCredentials = async (
|
|
|
208
208
|
continue
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
const mapSelectableCredentialPromises = value.valid_credentials.map(async cred => {
|
|
211
|
+
const mapSelectableCredentialPromises = value.valid_credentials.map(async (cred) => {
|
|
212
212
|
const matchedCredential = uniqueCredentials[cred.input_credential_index]
|
|
213
213
|
const credentialBranding = branding.filter((cb) => cb.vcHash === matchedCredential.hash)
|
|
214
214
|
const issuerPartyIdentity = await agent.cmGetContacts({
|
|
@@ -246,3 +246,33 @@ export const translateCorrelationIdToName = async (correlationId: string, contex
|
|
|
246
246
|
|
|
247
247
|
return contacts[0].contact.displayName
|
|
248
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
|
+
}
|