@sphereon/ssi-sdk.siopv2-oid4vp-op-auth 0.34.1-fix.117 → 0.34.1-fix.141
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 +13 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/package.json +19 -19
- package/src/agent/DidAuthSiopOpAuthenticator.ts +4 -21
- package/src/services/Siopv2MachineService.ts +75 -101
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.141+ea643e42",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -31,21 +31,21 @@
|
|
|
31
31
|
"@sphereon/oid4vc-common": "0.19.1-feature.DIIPv4.106",
|
|
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.141+ea643e42",
|
|
35
|
+
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.34.1-fix.141+ea643e42",
|
|
36
|
+
"@sphereon/ssi-sdk-ext.jwt-service": "0.34.1-fix.141+ea643e42",
|
|
37
|
+
"@sphereon/ssi-sdk.contact-manager": "0.34.1-fix.141+ea643e42",
|
|
38
|
+
"@sphereon/ssi-sdk.core": "0.34.1-fix.141+ea643e42",
|
|
39
|
+
"@sphereon/ssi-sdk.credential-store": "0.34.1-fix.141+ea643e42",
|
|
40
|
+
"@sphereon/ssi-sdk.credential-validation": "0.34.1-fix.141+ea643e42",
|
|
41
|
+
"@sphereon/ssi-sdk.data-store": "0.34.1-fix.141+ea643e42",
|
|
42
|
+
"@sphereon/ssi-sdk.issuance-branding": "0.34.1-fix.141+ea643e42",
|
|
43
|
+
"@sphereon/ssi-sdk.pd-manager": "0.34.1-fix.141+ea643e42",
|
|
44
|
+
"@sphereon/ssi-sdk.presentation-exchange": "0.34.1-fix.141+ea643e42",
|
|
45
|
+
"@sphereon/ssi-sdk.sd-jwt": "0.34.1-fix.141+ea643e42",
|
|
46
|
+
"@sphereon/ssi-sdk.siopv2-oid4vp-common": "0.34.1-fix.141+ea643e42",
|
|
47
|
+
"@sphereon/ssi-sdk.xstate-machine-persistence": "0.34.1-fix.141+ea643e42",
|
|
48
|
+
"@sphereon/ssi-types": "0.34.1-fix.141+ea643e42",
|
|
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.141+ea643e42",
|
|
63
|
+
"@sphereon/ssi-sdk.agent-config": "0.34.1-fix.141+ea643e42",
|
|
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": "ea643e42804501f2a323a73971465d527981123d"
|
|
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'
|
|
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
|
|
@@ -1,34 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AuthorizationRequest,
|
|
3
|
-
Json,
|
|
4
|
-
SupportedVersion
|
|
5
|
-
} from '@sphereon/did-auth-siop'
|
|
1
|
+
import { AuthorizationRequest, Json, SupportedVersion } from '@sphereon/did-auth-siop'
|
|
6
2
|
import { isOID4VCIssuerIdentifier, ManagedIdentifierOptsOrResult } from '@sphereon/ssi-sdk-ext.identifier-resolution'
|
|
7
3
|
import { UniqueDigitalCredential, verifiableCredentialForRoleFilter } from '@sphereon/ssi-sdk.credential-store'
|
|
8
|
-
import { ConnectionType
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
Loggers,
|
|
13
|
-
OriginalVerifiableCredential,
|
|
14
|
-
SdJwtDecodedVerifiableCredential
|
|
15
|
-
} from '@sphereon/ssi-types'
|
|
4
|
+
import { ConnectionType } from '@sphereon/ssi-sdk.data-store'
|
|
5
|
+
import { CredentialRole } from '@sphereon/ssi-types'
|
|
6
|
+
|
|
7
|
+
import { CredentialMapper, HasherSync, Loggers, OriginalVerifiableCredential, SdJwtDecodedVerifiableCredential } from '@sphereon/ssi-types'
|
|
16
8
|
import { OpSession } from '../session'
|
|
17
|
-
import {
|
|
18
|
-
LOGGER_NAMESPACE,
|
|
19
|
-
RequiredContext,
|
|
20
|
-
SelectableCredential,
|
|
21
|
-
SelectableCredentialsMap,
|
|
22
|
-
Siopv2HolderEvent
|
|
23
|
-
} from '../types'
|
|
9
|
+
import { LOGGER_NAMESPACE, RequiredContext, SelectableCredential, SelectableCredentialsMap, Siopv2HolderEvent } from '../types'
|
|
24
10
|
import { encodeJoseBlob } from '@sphereon/ssi-sdk.core'
|
|
25
11
|
import { DcqlPresentation, DcqlQuery } from 'dcql'
|
|
26
12
|
import { convertToDcqlCredentials } from '../utils/dcql'
|
|
27
13
|
import { IAgentContext, IDIDManager } from '@veramo/core'
|
|
28
|
-
import {
|
|
29
|
-
getOrCreatePrimaryIdentifier,
|
|
30
|
-
SupportedDidMethodEnum
|
|
31
|
-
} from '@sphereon/ssi-sdk-ext.did-utils'
|
|
14
|
+
import { getOrCreatePrimaryIdentifier, SupportedDidMethodEnum } from '@sphereon/ssi-sdk-ext.did-utils'
|
|
32
15
|
|
|
33
16
|
export const logger = Loggers.DEFAULT.get(LOGGER_NAMESPACE)
|
|
34
17
|
|
|
@@ -76,68 +59,64 @@ export const siopSendAuthorizationResponse = async (
|
|
|
76
59
|
logger.debug(`AUD: ${aud}`)
|
|
77
60
|
logger.debug(JSON.stringify(request.authorizationRequest))
|
|
78
61
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return Promise.reject(Error('SiopMachine only supports UniqueDigitalCredentials for now'))
|
|
90
|
-
}
|
|
62
|
+
const domain =
|
|
63
|
+
((await request.authorizationRequest.getMergedProperty('client_id')) as string) ??
|
|
64
|
+
request.issuer ??
|
|
65
|
+
(request.versions.includes(SupportedVersion.JWT_VC_PRESENTATION_PROFILE_v1) ? 'https://self-issued.me/v2/openid-vc' : 'https://self-issued.me/v2')
|
|
66
|
+
logger.debug(`NONCE: ${session.nonce}, domain: ${domain}`)
|
|
67
|
+
|
|
68
|
+
const firstUniqueDC = credentials[0]
|
|
69
|
+
if (typeof firstUniqueDC !== 'object' || !('digitalCredential' in firstUniqueDC)) {
|
|
70
|
+
return Promise.reject(Error('SiopMachine only supports UniqueDigitalCredentials for now'))
|
|
71
|
+
}
|
|
91
72
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
73
|
+
let identifier: ManagedIdentifierOptsOrResult
|
|
74
|
+
const digitalCredential = firstUniqueDC.digitalCredential
|
|
75
|
+
const firstVC = firstUniqueDC.uniformVerifiableCredential
|
|
76
|
+
const holder = CredentialMapper.isSdJwtDecodedCredential(firstVC)
|
|
77
|
+
? firstVC.decodedPayload.cnf?.jwk
|
|
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 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
|
|
80
|
+
`did:jwk:${encodeJoseBlob(firstVC.decodedPayload.cnf?.jwk)}#0`
|
|
81
|
+
: firstVC.decodedPayload.sub
|
|
82
|
+
: Array.isArray(firstVC.credentialSubject)
|
|
83
|
+
? firstVC.credentialSubject[0].id
|
|
84
|
+
: firstVC.credentialSubject.id
|
|
85
|
+
if (!digitalCredential.kmsKeyRef) {
|
|
86
|
+
// In case the store does not have the kmsKeyRef lets search for the holder
|
|
87
|
+
|
|
88
|
+
if (!holder) {
|
|
89
|
+
return Promise.reject(`No holder found and no kmsKeyRef in DB. Cannot determine identifier to use`)
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
identifier = await session.context.agent.identifierManagedGet({ identifier: holder })
|
|
93
|
+
} catch (e) {
|
|
94
|
+
logger.debug(`Holder DID not found: ${holder}`)
|
|
95
|
+
throw e
|
|
96
|
+
}
|
|
97
|
+
} else if (isOID4VCIssuerIdentifier(digitalCredential.kmsKeyRef)) {
|
|
98
|
+
identifier = await session.context.agent.identifierManagedGetByOID4VCIssuer({
|
|
99
|
+
identifier: firstUniqueDC.digitalCredential.kmsKeyRef,
|
|
100
|
+
})
|
|
101
|
+
} else {
|
|
102
|
+
switch (digitalCredential.subjectCorrelationType) {
|
|
103
|
+
case 'DID':
|
|
104
|
+
identifier = await session.context.agent.identifierManagedGetByDid({
|
|
105
|
+
identifier: digitalCredential.subjectCorrelationId ?? holder,
|
|
106
|
+
kmsKeyRef: digitalCredential.kmsKeyRef,
|
|
119
107
|
})
|
|
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
|
-
}
|
|
108
|
+
break
|
|
109
|
+
// TODO other implementations?
|
|
110
|
+
default:
|
|
111
|
+
// Since we are using the kmsKeyRef we will find the KID regardless of the identifier. We set it for later access though
|
|
112
|
+
identifier = await session.context.agent.identifierManagedGetByKid({
|
|
113
|
+
identifier: digitalCredential.subjectCorrelationId ?? holder ?? digitalCredential.kmsKeyRef,
|
|
114
|
+
kmsKeyRef: digitalCredential.kmsKeyRef,
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
}
|
|
137
118
|
|
|
138
|
-
const dcqlCredentialsWithCredentials = new Map(
|
|
139
|
-
credentials.map((vc) => [convertToDcqlCredentials(vc), vc])
|
|
140
|
-
)
|
|
119
|
+
const dcqlCredentialsWithCredentials = new Map(credentials.map((vc) => [convertToDcqlCredentials(vc), vc]))
|
|
141
120
|
|
|
142
121
|
const queryResult = DcqlQuery.query(request.dcqlQuery, Array.from(dcqlCredentialsWithCredentials.keys()))
|
|
143
122
|
|
|
@@ -149,7 +128,7 @@ export const siopSendAuthorizationResponse = async (
|
|
|
149
128
|
const uniqueCredentials = Array.from(dcqlCredentialsWithCredentials.values())
|
|
150
129
|
for (const [key, value] of Object.entries(queryResult.credential_matches)) {
|
|
151
130
|
if (value.success) {
|
|
152
|
-
const matchedCredentials = value.valid_credentials.map(cred => uniqueCredentials[cred.input_credential_index])
|
|
131
|
+
const matchedCredentials = value.valid_credentials.map((cred) => uniqueCredentials[cred.input_credential_index])
|
|
153
132
|
const vc = matchedCredentials[0] // taking the first match for now //uniqueCredentials[value.input_credential_index]
|
|
154
133
|
if (!vc) {
|
|
155
134
|
continue
|
|
@@ -159,22 +138,22 @@ export const siopSendAuthorizationResponse = async (
|
|
|
159
138
|
continue
|
|
160
139
|
}
|
|
161
140
|
if (originalVc) {
|
|
162
|
-
presentation[key] = originalVc as
|
|
141
|
+
presentation[key] = originalVc as string | { [x: string]: Json }
|
|
163
142
|
}
|
|
164
143
|
}
|
|
165
144
|
}
|
|
166
145
|
|
|
167
146
|
const dcqlPresentation = DcqlPresentation.parse(presentation)
|
|
168
147
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
148
|
+
const response = session.sendAuthorizationResponse({
|
|
149
|
+
responseSignerOpts: identifier,
|
|
150
|
+
dcqlResponse: {
|
|
151
|
+
dcqlPresentation,
|
|
152
|
+
},
|
|
153
|
+
})
|
|
175
154
|
|
|
176
|
-
|
|
177
|
-
|
|
155
|
+
logger.debug(`Response: `, response)
|
|
156
|
+
return response
|
|
178
157
|
}
|
|
179
158
|
|
|
180
159
|
const retrieveEncodedCredential = (credential: UniqueDigitalCredential): OriginalVerifiableCredential | undefined => {
|
|
@@ -186,19 +165,14 @@ const retrieveEncodedCredential = (credential: UniqueDigitalCredential): Origina
|
|
|
186
165
|
: credential.originalVerifiableCredential
|
|
187
166
|
}
|
|
188
167
|
|
|
189
|
-
export const getSelectableCredentials = async (
|
|
190
|
-
dcqlQuery: DcqlQuery,
|
|
191
|
-
context: RequiredContext,
|
|
192
|
-
): Promise<SelectableCredentialsMap> => {
|
|
168
|
+
export const getSelectableCredentials = async (dcqlQuery: DcqlQuery, context: RequiredContext): Promise<SelectableCredentialsMap> => {
|
|
193
169
|
const agentContext = { ...context, agent: context.agent }
|
|
194
170
|
const { agent } = agentContext
|
|
195
171
|
const uniqueVerifiableCredentials = await agent.crsGetUniqueCredentials({
|
|
196
172
|
filter: verifiableCredentialForRoleFilter(CredentialRole.HOLDER),
|
|
197
173
|
})
|
|
198
174
|
const branding = await agent.ibGetCredentialBranding()
|
|
199
|
-
const dcqlCredentialsWithCredentials = new Map(
|
|
200
|
-
uniqueVerifiableCredentials.map((vc) => [convertToDcqlCredentials(vc), vc])
|
|
201
|
-
)
|
|
175
|
+
const dcqlCredentialsWithCredentials = new Map(uniqueVerifiableCredentials.map((vc) => [convertToDcqlCredentials(vc), vc]))
|
|
202
176
|
const queryResult = DcqlQuery.query(dcqlQuery, Array.from(dcqlCredentialsWithCredentials.keys()))
|
|
203
177
|
const uniqueCredentials = Array.from(dcqlCredentialsWithCredentials.values())
|
|
204
178
|
const selectableCredentialsMap: SelectableCredentialsMap = new Map()
|
|
@@ -208,7 +182,7 @@ export const getSelectableCredentials = async (
|
|
|
208
182
|
continue
|
|
209
183
|
}
|
|
210
184
|
|
|
211
|
-
const mapSelectableCredentialPromises = value.valid_credentials.map(async cred => {
|
|
185
|
+
const mapSelectableCredentialPromises = value.valid_credentials.map(async (cred) => {
|
|
212
186
|
const matchedCredential = uniqueCredentials[cred.input_credential_index]
|
|
213
187
|
const credentialBranding = branding.filter((cb) => cb.vcHash === matchedCredential.hash)
|
|
214
188
|
const issuerPartyIdentity = await agent.cmGetContacts({
|