@sphereon/ssi-sdk.siopv2-oid4vp-op-auth 0.34.1-feature.SSISDK.26.55 → 0.34.1-feature.SSISDK.26.75
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 +1026 -1547
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +709 -111
- package/dist/index.d.ts +709 -111
- package/dist/index.js +1036 -1557
- package/dist/index.js.map +1 -1
- package/package.json +23 -23
- package/src/agent/DidAuthSiopOpAuthenticator.ts +19 -147
- package/src/index.ts +2 -1
- package/src/machine/Siopv2Machine.ts +4 -4
- package/src/services/Siopv2MachineService.ts +97 -203
- package/src/session/OID4VP.ts +310 -299
- package/src/session/OpSession.ts +22 -114
- package/src/types/IDidAuthSiopOpAuthenticator.ts +5 -58
- package/src/types/identifier/index.ts +0 -4
- package/src/types/siop-service/index.ts +1 -3
- package/src/utils/CredentialUtils.ts +1 -39
- package/src/utils/dcql.ts +21 -19
package/dist/index.js
CHANGED
|
@@ -35,512 +35,351 @@ var require_nl = __commonJS({
|
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
// plugin.schema.json
|
|
38
|
-
var
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
sessionId: {
|
|
48
|
-
type: "string"
|
|
49
|
-
},
|
|
50
|
-
additionalProperties: false
|
|
51
|
-
},
|
|
52
|
-
required: ["sessionId"],
|
|
53
|
-
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.getSessionForSiop } "
|
|
38
|
+
var plugin_schema_default = {
|
|
39
|
+
IDidAuthSiopOpAuthenticator: {
|
|
40
|
+
components: {
|
|
41
|
+
schemas: {
|
|
42
|
+
IGetSiopSessionArgs: {
|
|
43
|
+
type: "object",
|
|
44
|
+
properties: {
|
|
45
|
+
sessionId: {
|
|
46
|
+
type: "string"
|
|
54
47
|
},
|
|
55
|
-
|
|
48
|
+
additionalProperties: false
|
|
49
|
+
},
|
|
50
|
+
required: ["sessionId"],
|
|
51
|
+
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.getSessionForSiop } "
|
|
52
|
+
},
|
|
53
|
+
IRegisterSiopSessionArgs: {
|
|
54
|
+
type: "object",
|
|
55
|
+
properties: {
|
|
56
|
+
identifier: {
|
|
56
57
|
type: "object",
|
|
57
58
|
properties: {
|
|
58
|
-
|
|
59
|
-
type: "object",
|
|
60
|
-
properties: {
|
|
61
|
-
did: {
|
|
62
|
-
type: "string"
|
|
63
|
-
},
|
|
64
|
-
alias: {
|
|
65
|
-
type: "string"
|
|
66
|
-
},
|
|
67
|
-
provider: {
|
|
68
|
-
type: "string"
|
|
69
|
-
},
|
|
70
|
-
controllerKeyId: {
|
|
71
|
-
type: "string"
|
|
72
|
-
},
|
|
73
|
-
keys: {
|
|
74
|
-
type: "array",
|
|
75
|
-
items: {
|
|
76
|
-
type: "object",
|
|
77
|
-
properties: {
|
|
78
|
-
additionalProperties: true
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
services: {
|
|
83
|
-
type: "array",
|
|
84
|
-
items: {
|
|
85
|
-
type: "object",
|
|
86
|
-
properties: {
|
|
87
|
-
additionalProperties: true
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
additionalProperties: false,
|
|
93
|
-
required: ["did", "provider", "keys", "services"]
|
|
94
|
-
},
|
|
95
|
-
sessionId: {
|
|
59
|
+
did: {
|
|
96
60
|
type: "string"
|
|
97
61
|
},
|
|
98
|
-
|
|
99
|
-
type: "number"
|
|
100
|
-
},
|
|
101
|
-
additionalProperties: false
|
|
102
|
-
},
|
|
103
|
-
required: ["identifier"],
|
|
104
|
-
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.registerSessionForSiop } "
|
|
105
|
-
},
|
|
106
|
-
IRemoveSiopSessionArgs: {
|
|
107
|
-
type: "object",
|
|
108
|
-
properties: {
|
|
109
|
-
sessionId: {
|
|
62
|
+
alias: {
|
|
110
63
|
type: "string"
|
|
111
64
|
},
|
|
112
|
-
|
|
113
|
-
},
|
|
114
|
-
required: ["sessionId"],
|
|
115
|
-
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.removeSessionForSiop } "
|
|
116
|
-
},
|
|
117
|
-
IAuthenticateWithSiopArgs: {
|
|
118
|
-
type: "object",
|
|
119
|
-
properties: {
|
|
120
|
-
sessionId: {
|
|
65
|
+
provider: {
|
|
121
66
|
type: "string"
|
|
122
67
|
},
|
|
123
|
-
|
|
68
|
+
controllerKeyId: {
|
|
124
69
|
type: "string"
|
|
125
70
|
},
|
|
126
|
-
|
|
127
|
-
type: "
|
|
71
|
+
keys: {
|
|
72
|
+
type: "array",
|
|
73
|
+
items: {
|
|
74
|
+
type: "object",
|
|
75
|
+
properties: {
|
|
76
|
+
additionalProperties: true
|
|
77
|
+
}
|
|
78
|
+
}
|
|
128
79
|
},
|
|
129
|
-
|
|
80
|
+
services: {
|
|
81
|
+
type: "array",
|
|
82
|
+
items: {
|
|
83
|
+
type: "object",
|
|
84
|
+
properties: {
|
|
85
|
+
additionalProperties: true
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
130
89
|
},
|
|
131
|
-
|
|
132
|
-
|
|
90
|
+
additionalProperties: false,
|
|
91
|
+
required: ["did", "provider", "keys", "services"]
|
|
92
|
+
},
|
|
93
|
+
sessionId: {
|
|
94
|
+
type: "string"
|
|
95
|
+
},
|
|
96
|
+
expiresIn: {
|
|
97
|
+
type: "number"
|
|
133
98
|
},
|
|
134
|
-
|
|
99
|
+
additionalProperties: false
|
|
100
|
+
},
|
|
101
|
+
required: ["identifier"],
|
|
102
|
+
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.registerSessionForSiop } "
|
|
103
|
+
},
|
|
104
|
+
IRemoveSiopSessionArgs: {
|
|
105
|
+
type: "object",
|
|
106
|
+
properties: {
|
|
107
|
+
sessionId: {
|
|
108
|
+
type: "string"
|
|
109
|
+
},
|
|
110
|
+
additionalProperties: false
|
|
111
|
+
},
|
|
112
|
+
required: ["sessionId"],
|
|
113
|
+
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.removeSessionForSiop } "
|
|
114
|
+
},
|
|
115
|
+
IAuthenticateWithSiopArgs: {
|
|
116
|
+
type: "object",
|
|
117
|
+
properties: {
|
|
118
|
+
sessionId: {
|
|
119
|
+
type: "string"
|
|
120
|
+
},
|
|
121
|
+
stateId: {
|
|
122
|
+
type: "string"
|
|
123
|
+
},
|
|
124
|
+
redirectUrl: {
|
|
125
|
+
type: "string"
|
|
126
|
+
},
|
|
127
|
+
additionalProperties: false
|
|
128
|
+
},
|
|
129
|
+
required: ["sessionId", "stateId", "redirectUrl"],
|
|
130
|
+
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.authenticateWithSiop } "
|
|
131
|
+
},
|
|
132
|
+
IResponse: {
|
|
133
|
+
type: "object",
|
|
134
|
+
properties: {
|
|
135
|
+
status: {
|
|
136
|
+
type: "number"
|
|
137
|
+
},
|
|
138
|
+
additionalProperties: true
|
|
139
|
+
},
|
|
140
|
+
required: ["status"],
|
|
141
|
+
description: "Result of {@link DidAuthSiopOpAuthenticator.authenticateWithSiop & DidAuthSiopOpAuthenticator.sendSiopAuthenticationResponse } "
|
|
142
|
+
},
|
|
143
|
+
IGetSiopAuthenticationRequestFromRpArgs: {
|
|
144
|
+
type: "object",
|
|
145
|
+
properties: {
|
|
146
|
+
sessionId: {
|
|
147
|
+
type: "string"
|
|
148
|
+
},
|
|
149
|
+
stateId: {
|
|
150
|
+
type: "string"
|
|
151
|
+
},
|
|
152
|
+
redirectUrl: {
|
|
153
|
+
type: "string"
|
|
154
|
+
},
|
|
155
|
+
additionalProperties: false
|
|
156
|
+
},
|
|
157
|
+
required: ["sessionId", "stateId", "redirectUrl"],
|
|
158
|
+
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.getSiopAuthenticationRequestFromRP } "
|
|
159
|
+
},
|
|
160
|
+
ParsedAuthenticationRequestURI: {
|
|
161
|
+
type: "object",
|
|
162
|
+
properties: {
|
|
163
|
+
jwt: {
|
|
164
|
+
type: "string"
|
|
165
|
+
},
|
|
166
|
+
requestPayload: {
|
|
135
167
|
type: "object",
|
|
136
168
|
properties: {
|
|
137
|
-
status: {
|
|
138
|
-
type: "number"
|
|
139
|
-
},
|
|
140
169
|
additionalProperties: true
|
|
141
|
-
}
|
|
142
|
-
required: ["status"],
|
|
143
|
-
description: "Result of {@link DidAuthSiopOpAuthenticator.authenticateWithSiop & DidAuthSiopOpAuthenticator.sendSiopAuthenticationResponse } "
|
|
170
|
+
}
|
|
144
171
|
},
|
|
145
|
-
|
|
172
|
+
registration: {
|
|
146
173
|
type: "object",
|
|
147
174
|
properties: {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
},
|
|
151
|
-
stateId: {
|
|
152
|
-
type: "string"
|
|
153
|
-
},
|
|
154
|
-
redirectUrl: {
|
|
155
|
-
type: "string"
|
|
156
|
-
},
|
|
157
|
-
additionalProperties: false
|
|
158
|
-
},
|
|
159
|
-
required: ["sessionId", "stateId", "redirectUrl"],
|
|
160
|
-
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.getSiopAuthenticationRequestFromRP } "
|
|
175
|
+
additionalProperties: true
|
|
176
|
+
}
|
|
161
177
|
},
|
|
162
|
-
|
|
178
|
+
additionalProperties: false
|
|
179
|
+
},
|
|
180
|
+
required: ["jwt", "requestPayload", "registration"],
|
|
181
|
+
description: "Result of {@link DidAuthSiopOpAuthenticator.getSiopAuthenticationRequestFromRP } "
|
|
182
|
+
},
|
|
183
|
+
IGetSiopAuthenticationRequestDetailsArgs: {
|
|
184
|
+
type: "object",
|
|
185
|
+
properties: {
|
|
186
|
+
sessionId: {
|
|
187
|
+
type: "string"
|
|
188
|
+
},
|
|
189
|
+
verifiedAuthenticationRequest: {
|
|
163
190
|
type: "object",
|
|
164
191
|
properties: {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
},
|
|
168
|
-
requestPayload: {
|
|
169
|
-
type: "object",
|
|
170
|
-
properties: {
|
|
171
|
-
additionalProperties: true
|
|
172
|
-
}
|
|
173
|
-
},
|
|
174
|
-
registration: {
|
|
175
|
-
type: "object",
|
|
176
|
-
properties: {
|
|
177
|
-
additionalProperties: true
|
|
178
|
-
}
|
|
179
|
-
},
|
|
180
|
-
additionalProperties: false
|
|
181
|
-
},
|
|
182
|
-
required: ["jwt", "requestPayload", "registration"],
|
|
183
|
-
description: "Result of {@link DidAuthSiopOpAuthenticator.getSiopAuthenticationRequestFromRP } "
|
|
192
|
+
additionalProperties: true
|
|
193
|
+
}
|
|
184
194
|
},
|
|
185
|
-
|
|
195
|
+
credentialFilter: {
|
|
186
196
|
type: "object",
|
|
187
197
|
properties: {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
additionalProperties: false
|
|
204
|
-
},
|
|
205
|
-
required: ["sessionId", "verifiedAuthenticationRequest"],
|
|
206
|
-
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.getSiopAuthenticationRequestDetails } "
|
|
198
|
+
additionalProperties: true
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
additionalProperties: false
|
|
202
|
+
},
|
|
203
|
+
required: ["sessionId", "verifiedAuthenticationRequest"],
|
|
204
|
+
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.getSiopAuthenticationRequestDetails } "
|
|
205
|
+
},
|
|
206
|
+
IAuthRequestDetails: {
|
|
207
|
+
type: "object",
|
|
208
|
+
properties: {
|
|
209
|
+
id: {
|
|
210
|
+
type: "string"
|
|
207
211
|
},
|
|
208
|
-
|
|
212
|
+
alsoKnownAs: {
|
|
213
|
+
type: "array",
|
|
214
|
+
items: {
|
|
215
|
+
type: "string"
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
vpResponseOpts: {
|
|
209
219
|
type: "object",
|
|
210
220
|
properties: {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
},
|
|
226
|
-
additionalProperties: false
|
|
227
|
-
},
|
|
228
|
-
required: ["id", "vpResponseOpts"],
|
|
229
|
-
description: "Result of {@link DidAuthSiopOpAuthenticator.getSiopAuthenticationRequestDetails } "
|
|
221
|
+
additionalProperties: true
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
additionalProperties: false
|
|
225
|
+
},
|
|
226
|
+
required: ["id", "vpResponseOpts"],
|
|
227
|
+
description: "Result of {@link DidAuthSiopOpAuthenticator.getSiopAuthenticationRequestDetails } "
|
|
228
|
+
},
|
|
229
|
+
IVerifySiopAuthenticationRequestUriArgs: {
|
|
230
|
+
type: "object",
|
|
231
|
+
properties: {
|
|
232
|
+
sessionId: {
|
|
233
|
+
type: "string"
|
|
230
234
|
},
|
|
231
|
-
|
|
235
|
+
ParsedAuthenticationRequestURI: {
|
|
232
236
|
type: "object",
|
|
233
237
|
properties: {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
},
|
|
237
|
-
ParsedAuthenticationRequestURI: {
|
|
238
|
-
type: "object",
|
|
239
|
-
properties: {
|
|
240
|
-
additionalProperties: true
|
|
241
|
-
}
|
|
242
|
-
},
|
|
243
|
-
additionalProperties: false
|
|
244
|
-
},
|
|
245
|
-
required: ["sessionId", "ParsedAuthenticationRequestURI"],
|
|
246
|
-
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.verifySiopAuthenticationRequestURI } "
|
|
238
|
+
additionalProperties: true
|
|
239
|
+
}
|
|
247
240
|
},
|
|
248
|
-
|
|
241
|
+
additionalProperties: false
|
|
242
|
+
},
|
|
243
|
+
required: ["sessionId", "ParsedAuthenticationRequestURI"],
|
|
244
|
+
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.verifySiopAuthenticationRequestURI } "
|
|
245
|
+
},
|
|
246
|
+
VerifiedAuthorizationRequest: {
|
|
247
|
+
type: "object",
|
|
248
|
+
properties: {
|
|
249
|
+
payload: {
|
|
249
250
|
type: "object",
|
|
250
251
|
properties: {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
properties: {
|
|
254
|
-
additionalProperties: true
|
|
255
|
-
}
|
|
256
|
-
},
|
|
257
|
-
presentationDefinitions: {
|
|
258
|
-
type: "object",
|
|
259
|
-
properties: {
|
|
260
|
-
additionalProperties: true
|
|
261
|
-
}
|
|
262
|
-
},
|
|
263
|
-
verifyOpts: {
|
|
264
|
-
type: "object",
|
|
265
|
-
properties: {
|
|
266
|
-
additionalProperties: true
|
|
267
|
-
}
|
|
268
|
-
},
|
|
269
|
-
additionalProperties: false
|
|
270
|
-
},
|
|
271
|
-
required: ["payload", "verifyOpts"],
|
|
272
|
-
description: "Result of {@link DidAuthSiopOpAuthenticator.verifySiopAuthenticationRequestURI } "
|
|
252
|
+
additionalProperties: true
|
|
253
|
+
}
|
|
273
254
|
},
|
|
274
|
-
|
|
255
|
+
presentationDefinitions: {
|
|
275
256
|
type: "object",
|
|
276
257
|
properties: {
|
|
277
|
-
|
|
278
|
-
type: "string"
|
|
279
|
-
},
|
|
280
|
-
verifiedAuthenticationRequest: {
|
|
281
|
-
type: "object",
|
|
282
|
-
properties: {
|
|
283
|
-
additionalProperties: true
|
|
284
|
-
}
|
|
285
|
-
},
|
|
286
|
-
verifiablePresentationResponse: {
|
|
287
|
-
type: "object",
|
|
288
|
-
properties: {
|
|
289
|
-
additionalProperties: true
|
|
290
|
-
}
|
|
291
|
-
},
|
|
292
|
-
additionalProperties: false
|
|
293
|
-
},
|
|
294
|
-
required: ["sessionId", "verifiedAuthenticationRequest"],
|
|
295
|
-
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.sendSiopAuthenticationResponse } "
|
|
296
|
-
}
|
|
297
|
-
},
|
|
298
|
-
methods: {
|
|
299
|
-
getSessionForSiop: {
|
|
300
|
-
description: "Get SIOP session",
|
|
301
|
-
arguments: {
|
|
302
|
-
$ref: "#/components/schemas/IGetSiopSessionArgs"
|
|
303
|
-
},
|
|
304
|
-
returnType: "object"
|
|
305
|
-
},
|
|
306
|
-
registerSessionForSiop: {
|
|
307
|
-
description: "Register SIOP session",
|
|
308
|
-
arguments: {
|
|
309
|
-
$ref: "#/components/schemas/IRegisterSiopSessionArgs"
|
|
310
|
-
},
|
|
311
|
-
returnType: "object"
|
|
312
|
-
},
|
|
313
|
-
removeSessionForSiop: {
|
|
314
|
-
description: "Remove SIOP session",
|
|
315
|
-
arguments: {
|
|
316
|
-
$ref: "#/components/schemas/IRemoveSiopSessionArgs"
|
|
317
|
-
},
|
|
318
|
-
returnType: "boolean"
|
|
319
|
-
},
|
|
320
|
-
authenticateWithSiop: {
|
|
321
|
-
description: "Authenticate using DID Auth SIOP",
|
|
322
|
-
arguments: {
|
|
323
|
-
$ref: "#/components/schemas/IAuthenticateWithSiopArgs"
|
|
324
|
-
},
|
|
325
|
-
returnType: {
|
|
326
|
-
$ref: "#/components/schemas/Response"
|
|
258
|
+
additionalProperties: true
|
|
327
259
|
}
|
|
328
260
|
},
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
},
|
|
334
|
-
returnType: {
|
|
335
|
-
$ref: "#/components/schemas/ParsedAuthenticationRequestURI"
|
|
261
|
+
verifyOpts: {
|
|
262
|
+
type: "object",
|
|
263
|
+
properties: {
|
|
264
|
+
additionalProperties: true
|
|
336
265
|
}
|
|
337
266
|
},
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
267
|
+
additionalProperties: false
|
|
268
|
+
},
|
|
269
|
+
required: ["payload", "verifyOpts"],
|
|
270
|
+
description: "Result of {@link DidAuthSiopOpAuthenticator.verifySiopAuthenticationRequestURI } "
|
|
271
|
+
},
|
|
272
|
+
ISendSiopAuthenticationResponseArgs: {
|
|
273
|
+
type: "object",
|
|
274
|
+
properties: {
|
|
275
|
+
sessionId: {
|
|
276
|
+
type: "string"
|
|
346
277
|
},
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
},
|
|
352
|
-
returnType: {
|
|
353
|
-
$ref: "#/components/schemas/VerifiedAuthorizationRequest"
|
|
278
|
+
verifiedAuthenticationRequest: {
|
|
279
|
+
type: "object",
|
|
280
|
+
properties: {
|
|
281
|
+
additionalProperties: true
|
|
354
282
|
}
|
|
355
283
|
},
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
},
|
|
361
|
-
returnType: {
|
|
362
|
-
$ref: "#/components/schemas/IRequiredContext"
|
|
284
|
+
verifiablePresentationResponse: {
|
|
285
|
+
type: "object",
|
|
286
|
+
properties: {
|
|
287
|
+
additionalProperties: true
|
|
363
288
|
}
|
|
364
|
-
}
|
|
289
|
+
},
|
|
290
|
+
additionalProperties: false
|
|
291
|
+
},
|
|
292
|
+
required: ["sessionId", "verifiedAuthenticationRequest"],
|
|
293
|
+
description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.sendSiopAuthenticationResponse } "
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
methods: {
|
|
297
|
+
getSessionForSiop: {
|
|
298
|
+
description: "Get SIOP session",
|
|
299
|
+
arguments: {
|
|
300
|
+
$ref: "#/components/schemas/IGetSiopSessionArgs"
|
|
301
|
+
},
|
|
302
|
+
returnType: "object"
|
|
303
|
+
},
|
|
304
|
+
registerSessionForSiop: {
|
|
305
|
+
description: "Register SIOP session",
|
|
306
|
+
arguments: {
|
|
307
|
+
$ref: "#/components/schemas/IRegisterSiopSessionArgs"
|
|
308
|
+
},
|
|
309
|
+
returnType: "object"
|
|
310
|
+
},
|
|
311
|
+
removeSessionForSiop: {
|
|
312
|
+
description: "Remove SIOP session",
|
|
313
|
+
arguments: {
|
|
314
|
+
$ref: "#/components/schemas/IRemoveSiopSessionArgs"
|
|
315
|
+
},
|
|
316
|
+
returnType: "boolean"
|
|
317
|
+
},
|
|
318
|
+
authenticateWithSiop: {
|
|
319
|
+
description: "Authenticate using DID Auth SIOP",
|
|
320
|
+
arguments: {
|
|
321
|
+
$ref: "#/components/schemas/IAuthenticateWithSiopArgs"
|
|
322
|
+
},
|
|
323
|
+
returnType: {
|
|
324
|
+
$ref: "#/components/schemas/Response"
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
getSiopAuthenticationRequestFromRP: {
|
|
328
|
+
description: "Get authentication request from RP",
|
|
329
|
+
arguments: {
|
|
330
|
+
$ref: "#/components/schemas/IGetSiopAuthenticationRequestFromRpArgs"
|
|
331
|
+
},
|
|
332
|
+
returnType: {
|
|
333
|
+
$ref: "#/components/schemas/ParsedAuthenticationRequestURI"
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
getSiopAuthenticationRequestDetails: {
|
|
337
|
+
description: "Get authentication request details",
|
|
338
|
+
arguments: {
|
|
339
|
+
$ref: "#/components/schemas/IGetSiopAuthenticationRequestDetailsArgs"
|
|
340
|
+
},
|
|
341
|
+
returnType: {
|
|
342
|
+
$ref: "#/components/schemas/IAuthRequestDetails"
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
verifySiopAuthenticationRequestURI: {
|
|
346
|
+
description: "Verify authentication request URI",
|
|
347
|
+
arguments: {
|
|
348
|
+
$ref: "#/components/schemas/IVerifySiopAuthenticationRequestUriArgs"
|
|
349
|
+
},
|
|
350
|
+
returnType: {
|
|
351
|
+
$ref: "#/components/schemas/VerifiedAuthorizationRequest"
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
sendSiopAuthenticationResponse: {
|
|
355
|
+
description: "Send authentication response",
|
|
356
|
+
arguments: {
|
|
357
|
+
$ref: "#/components/schemas/ISendSiopAuthenticationResponseArgs"
|
|
358
|
+
},
|
|
359
|
+
returnType: {
|
|
360
|
+
$ref: "#/components/schemas/IRequiredContext"
|
|
365
361
|
}
|
|
366
362
|
}
|
|
367
363
|
}
|
|
368
|
-
}
|
|
364
|
+
}
|
|
369
365
|
}
|
|
370
|
-
}
|
|
366
|
+
};
|
|
371
367
|
|
|
372
368
|
// src/agent/DidAuthSiopOpAuthenticator.ts
|
|
373
|
-
import { decodeUriAsJson
|
|
374
|
-
import { ConnectionType as ConnectionType2, CorrelationIdentifierType,
|
|
369
|
+
import { decodeUriAsJson } from "@sphereon/did-auth-siop";
|
|
370
|
+
import { ConnectionType as ConnectionType2, CorrelationIdentifierType, CredentialRole as CredentialRole2, IdentityOrigin } from "@sphereon/ssi-sdk.data-store";
|
|
375
371
|
import { Loggers as Loggers4 } from "@sphereon/ssi-types";
|
|
376
372
|
import { v4 as uuidv4 } from "uuid";
|
|
377
373
|
|
|
378
|
-
// src/
|
|
379
|
-
import {
|
|
380
|
-
import { SigningAlgo } from "@sphereon/oid4vc-common";
|
|
381
|
-
import { isManagedIdentifierDidOpts, isManagedIdentifierX5cOpts } from "@sphereon/ssi-sdk-ext.identifier-resolution";
|
|
382
|
-
import { createPEXPresentationSignCallback } from "@sphereon/ssi-sdk.presentation-exchange";
|
|
383
|
-
import { EventEmitter } from "events";
|
|
384
|
-
async function createOID4VPPresentationSignCallback({ presentationSignCallback, idOpts: idOpts1, domain, fetchRemoteContexts, challenge, format, context, skipDidResolution }) {
|
|
385
|
-
if (typeof presentationSignCallback === "function") {
|
|
386
|
-
return presentationSignCallback;
|
|
387
|
-
}
|
|
388
|
-
return createPEXPresentationSignCallback({
|
|
389
|
-
idOpts: idOpts1,
|
|
390
|
-
fetchRemoteContexts,
|
|
391
|
-
domain,
|
|
392
|
-
challenge,
|
|
393
|
-
format,
|
|
394
|
-
skipDidResolution
|
|
395
|
-
}, context);
|
|
396
|
-
}
|
|
397
|
-
__name(createOID4VPPresentationSignCallback, "createOID4VPPresentationSignCallback");
|
|
398
|
-
async function createOPBuilder({ opOptions, idOpts: idOpts1, context }) {
|
|
399
|
-
const eventEmitter = opOptions.eventEmitter ?? new EventEmitter();
|
|
400
|
-
const builder = OP.builder().withResponseMode(opOptions.responseMode ?? ResponseMode.DIRECT_POST).withSupportedVersions(opOptions.supportedVersions ?? [
|
|
401
|
-
SupportedVersion.SIOPv2_ID1,
|
|
402
|
-
SupportedVersion.JWT_VC_PRESENTATION_PROFILE_v1,
|
|
403
|
-
SupportedVersion.SIOPv2_D11,
|
|
404
|
-
SupportedVersion.SIOPv2_D12_OID4VP_D18
|
|
405
|
-
]).withExpiresIn(opOptions.expiresIn ?? 300).withEventEmitter(eventEmitter).withRegistration({
|
|
406
|
-
passBy: PassBy.VALUE
|
|
407
|
-
});
|
|
408
|
-
const wellknownDIDVerifyCallback = opOptions.wellknownDIDVerifyCallback ? opOptions.wellknownDIDVerifyCallback : async (args) => {
|
|
409
|
-
const result = await context.agent.cvVerifyCredential({
|
|
410
|
-
credential: args.credential,
|
|
411
|
-
fetchRemoteContexts: true
|
|
412
|
-
});
|
|
413
|
-
return {
|
|
414
|
-
verified: result.result
|
|
415
|
-
};
|
|
416
|
-
};
|
|
417
|
-
builder.withVerifyJwtCallback(opOptions.verifyJwtCallback ? opOptions.verifyJwtCallback : getVerifyJwtCallback({
|
|
418
|
-
verifyOpts: {
|
|
419
|
-
wellknownDIDVerifyCallback,
|
|
420
|
-
checkLinkedDomain: "if_present"
|
|
421
|
-
}
|
|
422
|
-
}, context));
|
|
423
|
-
if (idOpts1) {
|
|
424
|
-
if (opOptions.skipDidResolution && isManagedIdentifierDidOpts(idOpts1)) {
|
|
425
|
-
idOpts1.offlineWhenNoDIDRegistered = true;
|
|
426
|
-
}
|
|
427
|
-
const createJwtCallback = createJwtCallbackWithIdOpts(idOpts1, context);
|
|
428
|
-
builder.withCreateJwtCallback(createJwtCallback);
|
|
429
|
-
builder.withPresentationSignCallback(await createOID4VPPresentationSignCallback({
|
|
430
|
-
presentationSignCallback: opOptions.presentationSignCallback,
|
|
431
|
-
skipDidResolution: opOptions.skipDidResolution ?? false,
|
|
432
|
-
idOpts: idOpts1,
|
|
433
|
-
context
|
|
434
|
-
}));
|
|
435
|
-
} else {
|
|
436
|
-
const createJwtCallback = createJwtCallbackWithOpOpts(opOptions, context);
|
|
437
|
-
builder.withCreateJwtCallback(createJwtCallback);
|
|
438
|
-
}
|
|
439
|
-
return builder;
|
|
440
|
-
}
|
|
441
|
-
__name(createOPBuilder, "createOPBuilder");
|
|
442
|
-
function createJwtCallbackWithIdOpts(idOpts1, context) {
|
|
443
|
-
return async (jwtIssuer, jwt) => {
|
|
444
|
-
let issuer;
|
|
445
|
-
if (isManagedIdentifierDidOpts(idOpts1)) {
|
|
446
|
-
issuer = {
|
|
447
|
-
...idOpts1,
|
|
448
|
-
method: idOpts1.method,
|
|
449
|
-
noIdentifierInHeader: false
|
|
450
|
-
};
|
|
451
|
-
} else if (isManagedIdentifierX5cOpts(idOpts1)) {
|
|
452
|
-
issuer = {
|
|
453
|
-
...idOpts1,
|
|
454
|
-
method: idOpts1.method,
|
|
455
|
-
noIdentifierInHeader: false
|
|
456
|
-
};
|
|
457
|
-
} else {
|
|
458
|
-
return Promise.reject(Error(`JWT issuer method ${jwtIssuer.method} not yet supported`));
|
|
459
|
-
}
|
|
460
|
-
const result = await context.agent.jwtCreateJwsCompactSignature({
|
|
461
|
-
issuer,
|
|
462
|
-
protectedHeader: jwt.header,
|
|
463
|
-
payload: jwt.payload
|
|
464
|
-
});
|
|
465
|
-
return result.jwt;
|
|
466
|
-
};
|
|
467
|
-
}
|
|
468
|
-
__name(createJwtCallbackWithIdOpts, "createJwtCallbackWithIdOpts");
|
|
469
|
-
function createJwtCallbackWithOpOpts(opOpts, context) {
|
|
470
|
-
return async (jwtIssuer, jwt) => {
|
|
471
|
-
let identifier;
|
|
472
|
-
if (jwtIssuer.method == "did") {
|
|
473
|
-
identifier = jwtIssuer.didUrl;
|
|
474
|
-
} else if (jwtIssuer.method == "x5c") {
|
|
475
|
-
identifier = jwtIssuer.x5c;
|
|
476
|
-
} else {
|
|
477
|
-
return Promise.reject(Error(`JWT issuer method ${jwtIssuer.method} not yet supported`));
|
|
478
|
-
}
|
|
479
|
-
const result = await context.agent.jwtCreateJwsCompactSignature({
|
|
480
|
-
// FIXME fix cose-key inference
|
|
481
|
-
// @ts-ignore
|
|
482
|
-
issuer: {
|
|
483
|
-
identifier,
|
|
484
|
-
kmsKeyRef: idOpts.kmsKeyRef,
|
|
485
|
-
noIdentifierInHeader: false
|
|
486
|
-
},
|
|
487
|
-
// FIXME fix JWK key_ops
|
|
488
|
-
// @ts-ignore
|
|
489
|
-
protectedHeader: jwt.header,
|
|
490
|
-
payload: jwt.payload
|
|
491
|
-
});
|
|
492
|
-
return result.jwt;
|
|
493
|
-
};
|
|
494
|
-
}
|
|
495
|
-
__name(createJwtCallbackWithOpOpts, "createJwtCallbackWithOpOpts");
|
|
496
|
-
function getVerifyJwtCallback(_opts, context) {
|
|
497
|
-
return async (_jwtVerifier, jwt) => {
|
|
498
|
-
const result = await context.agent.jwtVerifyJwsSignature({
|
|
499
|
-
jws: jwt.raw
|
|
500
|
-
});
|
|
501
|
-
console.log(result.message);
|
|
502
|
-
return !result.error;
|
|
503
|
-
};
|
|
504
|
-
}
|
|
505
|
-
__name(getVerifyJwtCallback, "getVerifyJwtCallback");
|
|
506
|
-
async function createOP({ opOptions, idOpts: idOpts1, context }) {
|
|
507
|
-
return (await createOPBuilder({
|
|
508
|
-
opOptions,
|
|
509
|
-
idOpts: idOpts1,
|
|
510
|
-
context
|
|
511
|
-
})).build();
|
|
512
|
-
}
|
|
513
|
-
__name(createOP, "createOP");
|
|
514
|
-
function getSigningAlgo(type) {
|
|
515
|
-
switch (type) {
|
|
516
|
-
case "Ed25519":
|
|
517
|
-
return SigningAlgo.EDDSA;
|
|
518
|
-
case "Secp256k1":
|
|
519
|
-
return SigningAlgo.ES256K;
|
|
520
|
-
case "Secp256r1":
|
|
521
|
-
return SigningAlgo.ES256;
|
|
522
|
-
// @ts-ignore
|
|
523
|
-
case "RSA":
|
|
524
|
-
return SigningAlgo.RS256;
|
|
525
|
-
default:
|
|
526
|
-
throw Error("Key type not yet supported");
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
__name(getSigningAlgo, "getSigningAlgo");
|
|
374
|
+
// src/machine/Siopv2Machine.ts
|
|
375
|
+
import { assign, createMachine, interpret } from "xstate";
|
|
530
376
|
|
|
531
|
-
// src/
|
|
532
|
-
import
|
|
533
|
-
import
|
|
534
|
-
import { isManagedIdentifierDidResult, isOID4VCIssuerIdentifier } from "@sphereon/ssi-sdk-ext.identifier-resolution";
|
|
535
|
-
import { defaultHasher } from "@sphereon/ssi-sdk.core";
|
|
536
|
-
import { verifiableCredentialForRoleFilter } from "@sphereon/ssi-sdk.credential-store";
|
|
377
|
+
// src/localization/Localization.ts
|
|
378
|
+
import i18n from "i18n-js";
|
|
379
|
+
import memoize from "lodash.memoize";
|
|
537
380
|
|
|
538
381
|
// src/types/IDidAuthSiopOpAuthenticator.ts
|
|
539
382
|
var LOGGER_NAMESPACE = "sphereon:siopv2-oid4vp:op-auth";
|
|
540
|
-
var events = /* @__PURE__ */ function(events2) {
|
|
541
|
-
events2["DID_SIOP_AUTHENTICATED"] = "didSiopAuthenticated";
|
|
542
|
-
return events2;
|
|
543
|
-
}({});
|
|
544
383
|
var DEFAULT_JWT_PROOF_TYPE = "JwtProof2020";
|
|
545
384
|
|
|
546
385
|
// src/types/siop-service/index.ts
|
|
@@ -613,646 +452,100 @@ var Siopv2MachineServices = /* @__PURE__ */ function(Siopv2MachineServices2) {
|
|
|
613
452
|
// src/types/identifier/index.ts
|
|
614
453
|
var DID_PREFIX = "did";
|
|
615
454
|
|
|
616
|
-
// src/
|
|
617
|
-
var
|
|
455
|
+
// src/localization/Localization.ts
|
|
456
|
+
var Localization = class Localization2 {
|
|
618
457
|
static {
|
|
619
|
-
__name(this, "
|
|
620
|
-
}
|
|
621
|
-
session;
|
|
622
|
-
allIdentifiers;
|
|
623
|
-
hasher;
|
|
624
|
-
constructor(args) {
|
|
625
|
-
const { session, allIdentifiers, hasher = defaultHasher } = args;
|
|
626
|
-
this.session = session;
|
|
627
|
-
this.allIdentifiers = allIdentifiers ?? [];
|
|
628
|
-
this.hasher = hasher;
|
|
629
|
-
}
|
|
630
|
-
static async init(session, allIdentifiers, hasher) {
|
|
631
|
-
return new _OID4VP({
|
|
632
|
-
session,
|
|
633
|
-
allIdentifiers: allIdentifiers ?? await session.getSupportedDIDs(),
|
|
634
|
-
hasher
|
|
635
|
-
});
|
|
636
|
-
}
|
|
637
|
-
async getPresentationDefinitions() {
|
|
638
|
-
const definitions = await this.session.getPresentationDefinitions();
|
|
639
|
-
if (definitions) {
|
|
640
|
-
PresentationExchange.assertValidPresentationDefinitionWithLocations(definitions);
|
|
641
|
-
}
|
|
642
|
-
return definitions;
|
|
643
|
-
}
|
|
644
|
-
getPresentationExchange(args) {
|
|
645
|
-
const { verifiableCredentials, allIdentifiers, hasher } = args;
|
|
646
|
-
return new PresentationExchange({
|
|
647
|
-
allDIDs: allIdentifiers ?? this.allIdentifiers,
|
|
648
|
-
allVerifiableCredentials: verifiableCredentials,
|
|
649
|
-
hasher: hasher ?? this.hasher
|
|
650
|
-
});
|
|
651
|
-
}
|
|
652
|
-
async createVerifiablePresentations(credentialRole, credentialsWithDefinitions, opts) {
|
|
653
|
-
return await Promise.all(credentialsWithDefinitions.map((cred) => this.createVerifiablePresentation(credentialRole, cred, opts)));
|
|
458
|
+
__name(this, "Localization");
|
|
654
459
|
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
domain: opts?.proofOpts?.domain ?? await this.session.getRedirectUri()
|
|
671
|
-
};
|
|
672
|
-
let idOpts2 = opts?.idOpts;
|
|
673
|
-
if (!idOpts2) {
|
|
674
|
-
if (opts?.subjectIsHolder) {
|
|
675
|
-
if (forceNoCredentialsInVP) {
|
|
676
|
-
return Promise.reject(Error(`Cannot have subject is holder, when force no credentials is being used, as we could never determine the holder then. Please provide holderDID`));
|
|
677
|
-
}
|
|
678
|
-
const firstUniqueDC = selectedVerifiableCredentials.credentials[0];
|
|
679
|
-
if (typeof firstUniqueDC !== "object" || !("digitalCredential" in firstUniqueDC)) {
|
|
680
|
-
return Promise.reject(Error("If no opts provided, credentials should be of type UniqueDigitalCredential"));
|
|
460
|
+
static translationGetters = {
|
|
461
|
+
[SupportedLanguage.ENGLISH]: () => require_en(),
|
|
462
|
+
[SupportedLanguage.DUTCH]: () => require_nl()
|
|
463
|
+
};
|
|
464
|
+
static translate = memoize((key, config) => {
|
|
465
|
+
if (Object.keys(i18n.translations).length === 0) {
|
|
466
|
+
i18n.translations = {
|
|
467
|
+
[SupportedLanguage.ENGLISH]: Localization2.translationGetters[SupportedLanguage.ENGLISH]()
|
|
468
|
+
};
|
|
469
|
+
i18n.locale = SupportedLanguage.ENGLISH;
|
|
470
|
+
} else {
|
|
471
|
+
i18n.translations = {
|
|
472
|
+
[i18n.locale]: {
|
|
473
|
+
...i18n.translations[i18n.locale],
|
|
474
|
+
...Localization2.translationGetters[this.findSupportedLanguage(i18n.locale) || SupportedLanguage.ENGLISH]()
|
|
681
475
|
}
|
|
682
|
-
|
|
683
|
-
identifier: firstUniqueDC.digitalCredential.kmsKeyRef
|
|
684
|
-
}) : await this.session.context.agent.identifierManagedGetByKid({
|
|
685
|
-
identifier: firstUniqueDC.digitalCredential.kmsKeyRef,
|
|
686
|
-
kmsKeyRef: firstUniqueDC.digitalCredential.kmsKeyRef
|
|
687
|
-
});
|
|
688
|
-
} else if (opts?.holder) {
|
|
689
|
-
idOpts2 = {
|
|
690
|
-
identifier: opts.holder
|
|
691
|
-
};
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
const vcs = forceNoCredentialsInVP ? selectedVerifiableCredentials : opts?.applyFilter ? await this.filterCredentials(credentialRole, selectedVerifiableCredentials.definition, {
|
|
695
|
-
restrictToFormats: opts?.restrictToFormats,
|
|
696
|
-
restrictToDIDMethods: opts?.restrictToDIDMethods,
|
|
697
|
-
filterOpts: {
|
|
698
|
-
verifiableCredentials: selectedVerifiableCredentials.credentials
|
|
699
|
-
}
|
|
700
|
-
}) : {
|
|
701
|
-
definition: selectedVerifiableCredentials.definition,
|
|
702
|
-
credentials: selectedVerifiableCredentials.credentials
|
|
703
|
-
};
|
|
704
|
-
if (!idOpts2) {
|
|
705
|
-
return Promise.reject(Error(`No identifier options present at this point`));
|
|
706
|
-
}
|
|
707
|
-
const signCallback = await createOID4VPPresentationSignCallback({
|
|
708
|
-
presentationSignCallback: this.session.options.presentationSignCallback,
|
|
709
|
-
idOpts: idOpts2,
|
|
710
|
-
context: this.session.context,
|
|
711
|
-
domain: proofOptions.domain,
|
|
712
|
-
challenge: proofOptions.challenge,
|
|
713
|
-
format: opts?.restrictToFormats ?? selectedVerifiableCredentials.definition.definition.format,
|
|
714
|
-
skipDidResolution: opts?.skipDidResolution ?? false
|
|
715
|
-
});
|
|
716
|
-
const identifier = await this.session.context.agent.identifierManagedGet(idOpts2);
|
|
717
|
-
const verifiableCredentials = vcs.credentials.map((credential) => typeof credential === "object" && "digitalCredential" in credential ? credential.originalVerifiableCredential : credential);
|
|
718
|
-
const presentationResult = await this.getPresentationExchange({
|
|
719
|
-
verifiableCredentials,
|
|
720
|
-
allIdentifiers: this.allIdentifiers,
|
|
721
|
-
hasher: opts?.hasher
|
|
722
|
-
}).createVerifiablePresentation(vcs.definition.definition, verifiableCredentials, signCallback, {
|
|
723
|
-
proofOptions,
|
|
724
|
-
// 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
|
|
725
|
-
...identifier && isManagedIdentifierDidResult(identifier) && {
|
|
726
|
-
holderDID: identifier.did
|
|
727
|
-
}
|
|
728
|
-
});
|
|
729
|
-
const verifiablePresentations = presentationResult.verifiablePresentations.map((verifiablePresentation) => typeof verifiablePresentation !== "string" && "proof" in verifiablePresentation && "jwt" in verifiablePresentation.proof && verifiablePresentation.proof.jwt ? verifiablePresentation.proof.jwt : verifiablePresentation);
|
|
730
|
-
return {
|
|
731
|
-
...presentationResult,
|
|
732
|
-
verifiablePresentations,
|
|
733
|
-
verifiableCredentials,
|
|
734
|
-
definition: selectedVerifiableCredentials.definition,
|
|
735
|
-
idOpts: idOpts2
|
|
736
|
-
};
|
|
737
|
-
}
|
|
738
|
-
async filterCredentialsAgainstAllDefinitions(credentialRole, opts) {
|
|
739
|
-
const defs = await this.getPresentationDefinitions();
|
|
740
|
-
const result = [];
|
|
741
|
-
if (defs) {
|
|
742
|
-
for (const definition of defs) {
|
|
743
|
-
result.push(await this.filterCredentials(credentialRole, definition, opts));
|
|
744
|
-
}
|
|
476
|
+
};
|
|
745
477
|
}
|
|
746
|
-
return
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
const
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
udcMap.set(credential.originalVerifiableCredential, credential);
|
|
753
|
-
} else {
|
|
754
|
-
udcMap.set(credential, credential);
|
|
755
|
-
}
|
|
756
|
-
});
|
|
757
|
-
const credentials = (await this.filterCredentialsWithSelectionStatus(credentialRole, presentationDefinition, {
|
|
758
|
-
...opts,
|
|
759
|
-
filterOpts: {
|
|
760
|
-
verifiableCredentials: opts?.filterOpts?.verifiableCredentials?.map((credential) => {
|
|
761
|
-
if (typeof credential === "object" && "digitalCredential" in credential) {
|
|
762
|
-
return credential.originalVerifiableCredential;
|
|
763
|
-
} else {
|
|
764
|
-
return credential;
|
|
765
|
-
}
|
|
766
|
-
})
|
|
478
|
+
return i18n.t(key, config);
|
|
479
|
+
}, (key, config) => config ? key + JSON.stringify(config) : key);
|
|
480
|
+
static findSupportedLanguage = /* @__PURE__ */ __name((locale) => {
|
|
481
|
+
for (const language of Object.values(SupportedLanguage)) {
|
|
482
|
+
if (language === locale) {
|
|
483
|
+
return language;
|
|
767
484
|
}
|
|
768
|
-
})).verifiableCredential;
|
|
769
|
-
return {
|
|
770
|
-
definition: presentationDefinition,
|
|
771
|
-
credentials: credentials?.map((vc) => udcMap.get(vc)) ?? []
|
|
772
|
-
};
|
|
773
|
-
}
|
|
774
|
-
async filterCredentialsWithSelectionStatus(credentialRole, presentationDefinition, opts) {
|
|
775
|
-
const selectionResults = await this.getPresentationExchange({
|
|
776
|
-
verifiableCredentials: await this.getCredentials(credentialRole, opts?.filterOpts)
|
|
777
|
-
}).selectVerifiableCredentialsForSubmission(presentationDefinition.definition, opts);
|
|
778
|
-
if (selectionResults.errors && selectionResults.errors.length > 0) {
|
|
779
|
-
throw Error(JSON.stringify(selectionResults.errors));
|
|
780
|
-
} else if (selectionResults.areRequiredCredentialsPresent === Status.ERROR) {
|
|
781
|
-
throw Error(`Not all required credentials are available to satisfy the relying party's request`);
|
|
782
485
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
}
|
|
789
|
-
async getCredentials(credentialRole, filterOpts) {
|
|
790
|
-
if (filterOpts?.verifiableCredentials && filterOpts.verifiableCredentials.length > 0) {
|
|
791
|
-
return filterOpts.verifiableCredentials;
|
|
792
|
-
}
|
|
793
|
-
const filter = verifiableCredentialForRoleFilter(credentialRole, filterOpts?.filter);
|
|
794
|
-
const uniqueCredentials = await this.session.context.agent.crsGetUniqueCredentials({
|
|
795
|
-
filter
|
|
796
|
-
});
|
|
797
|
-
return uniqueCredentials.map((uniqueVC) => {
|
|
798
|
-
const vc = uniqueVC.uniformVerifiableCredential;
|
|
799
|
-
const proof = Array.isArray(vc.proof) ? vc.proof : [
|
|
800
|
-
vc.proof
|
|
801
|
-
];
|
|
802
|
-
const jwtProof = proof.find((p) => p?.type === DEFAULT_JWT_PROOF_TYPE);
|
|
803
|
-
return jwtProof ? jwtProof.jwt : vc;
|
|
804
|
-
});
|
|
805
|
-
}
|
|
486
|
+
return void 0;
|
|
487
|
+
}, "findSupportedLanguage");
|
|
488
|
+
static getLocale = /* @__PURE__ */ __name(() => {
|
|
489
|
+
return i18n.locale || SupportedLanguage.ENGLISH;
|
|
490
|
+
}, "getLocale");
|
|
806
491
|
};
|
|
492
|
+
var translate = Localization.translate;
|
|
807
493
|
|
|
808
|
-
// src/
|
|
809
|
-
import { OP as OP2, URI } from "@sphereon/did-auth-siop";
|
|
810
|
-
import { getAgentDIDMethods, getAgentResolver } from "@sphereon/ssi-sdk-ext.did-utils";
|
|
811
|
-
import { encodeBase64url } from "@sphereon/ssi-sdk.core";
|
|
812
|
-
import { CredentialMapper, parseDid } from "@sphereon/ssi-types";
|
|
813
|
-
import { v4 } from "uuid";
|
|
814
|
-
import { PEX } from "@sphereon/pex";
|
|
494
|
+
// src/machine/Siopv2Machine.ts
|
|
815
495
|
import { Loggers } from "@sphereon/ssi-types";
|
|
816
|
-
var logger = Loggers.DEFAULT.get(
|
|
817
|
-
var
|
|
818
|
-
|
|
819
|
-
|
|
496
|
+
var logger = Loggers.DEFAULT.get(LOGGER_NAMESPACE);
|
|
497
|
+
var Siopv2HasNoContactGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
498
|
+
const { contact } = _ctx;
|
|
499
|
+
return contact === void 0;
|
|
500
|
+
}, "Siopv2HasNoContactGuard");
|
|
501
|
+
var Siopv2HasContactGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
502
|
+
const { contact } = _ctx;
|
|
503
|
+
return contact !== void 0;
|
|
504
|
+
}, "Siopv2HasContactGuard");
|
|
505
|
+
var Siopv2HasAuthorizationRequestGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
506
|
+
const { authorizationRequestData } = _ctx;
|
|
507
|
+
return authorizationRequestData !== void 0;
|
|
508
|
+
}, "Siopv2HasAuthorizationRequestGuard");
|
|
509
|
+
var Siopv2HasSelectableCredentialsAndContactGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
510
|
+
const { authorizationRequestData, contact } = _ctx;
|
|
511
|
+
if (!authorizationRequestData) {
|
|
512
|
+
throw new Error("Missing authorization request data in context");
|
|
820
513
|
}
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
options;
|
|
824
|
-
context;
|
|
825
|
-
requestJwtOrUri;
|
|
826
|
-
verifiedAuthorizationRequest;
|
|
827
|
-
_nonce;
|
|
828
|
-
_state;
|
|
829
|
-
_providedPresentationDefinitions;
|
|
830
|
-
constructor(options) {
|
|
831
|
-
this.id = options.sessionId;
|
|
832
|
-
this.options = options.op;
|
|
833
|
-
this.context = options.context;
|
|
834
|
-
this.requestJwtOrUri = options.requestJwtOrUri;
|
|
835
|
-
this._providedPresentationDefinitions = options.providedPresentationDefinitions;
|
|
514
|
+
if (!contact) {
|
|
515
|
+
throw new Error("Missing contact request data in context");
|
|
836
516
|
}
|
|
837
|
-
|
|
838
|
-
|
|
517
|
+
return authorizationRequestData.dcqlQuery !== void 0;
|
|
518
|
+
}, "Siopv2HasSelectableCredentialsAndContactGuard");
|
|
519
|
+
var Siopv2CreateContactGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
520
|
+
const { contactAlias, hasContactConsent } = _ctx;
|
|
521
|
+
return hasContactConsent && contactAlias !== void 0 && contactAlias.length > 0;
|
|
522
|
+
}, "Siopv2CreateContactGuard");
|
|
523
|
+
var Siopv2HasSelectedRequiredCredentialsGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
524
|
+
const { authorizationRequestData } = _ctx;
|
|
525
|
+
if (authorizationRequestData === void 0) {
|
|
526
|
+
throw new Error("Missing authorization request data in context");
|
|
839
527
|
}
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
const op = await createOP({
|
|
843
|
-
opOptions: this.options,
|
|
844
|
-
context: this.context
|
|
845
|
-
});
|
|
846
|
-
this.verifiedAuthorizationRequest = await op.verifyAuthorizationRequest(this.requestJwtOrUri);
|
|
847
|
-
this._nonce = await this.verifiedAuthorizationRequest.authorizationRequest.getMergedProperty("nonce");
|
|
848
|
-
this._state = await this.verifiedAuthorizationRequest.authorizationRequest.getMergedProperty("state");
|
|
849
|
-
await this.getSupportedDIDMethods();
|
|
850
|
-
}
|
|
851
|
-
return this.verifiedAuthorizationRequest;
|
|
528
|
+
if (authorizationRequestData.dcqlQuery === void 0) {
|
|
529
|
+
throw Error("No presentation definitions present");
|
|
852
530
|
}
|
|
853
|
-
|
|
854
|
-
|
|
531
|
+
return _ctx.selectedCredentials.length > 0;
|
|
532
|
+
}, "Siopv2HasSelectedRequiredCredentialsGuard");
|
|
533
|
+
var Siopv2IsSiopOnlyGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
534
|
+
const { authorizationRequestData } = _ctx;
|
|
535
|
+
if (authorizationRequestData === void 0) {
|
|
536
|
+
throw new Error("Missing authorization request data in context");
|
|
855
537
|
}
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
538
|
+
return authorizationRequestData.dcqlQuery === void 0;
|
|
539
|
+
}, "Siopv2IsSiopOnlyGuard");
|
|
540
|
+
var Siopv2IsSiopWithOID4VPGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
541
|
+
const { authorizationRequestData, selectableCredentialsMap } = _ctx;
|
|
542
|
+
if (!authorizationRequestData) {
|
|
543
|
+
throw new Error("Missing authorization request data in context");
|
|
861
544
|
}
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
throw Error("No state available. Please get authorization request first");
|
|
865
|
-
}
|
|
866
|
-
return this._state;
|
|
545
|
+
if (!selectableCredentialsMap) {
|
|
546
|
+
throw new Error("Missing selectableCredentialsMap in context");
|
|
867
547
|
}
|
|
868
|
-
|
|
869
|
-
this._nonce = void 0;
|
|
870
|
-
this._state = void 0;
|
|
871
|
-
this.verifiedAuthorizationRequest = void 0;
|
|
872
|
-
return this;
|
|
873
|
-
}
|
|
874
|
-
async getSupportedDIDMethods(didPrefix) {
|
|
875
|
-
const agentMethods = this.getAgentDIDMethodsSupported({
|
|
876
|
-
didPrefix
|
|
877
|
-
});
|
|
878
|
-
let rpMethods = await this.getRPDIDMethodsSupported({
|
|
879
|
-
didPrefix,
|
|
880
|
-
agentMethods
|
|
881
|
-
});
|
|
882
|
-
logger.debug(`RP supports subject syntax types: ${JSON.stringify(this.getSubjectSyntaxTypesSupported())}`);
|
|
883
|
-
if (rpMethods.dids.length === 0) {
|
|
884
|
-
logger.debug(`RP does not support DIDs. Supported: ${JSON.stringify(this.getSubjectSyntaxTypesSupported())}`);
|
|
885
|
-
return [];
|
|
886
|
-
}
|
|
887
|
-
let intersection;
|
|
888
|
-
if (rpMethods.dids.includes("did")) {
|
|
889
|
-
intersection = agentMethods && agentMethods.length > 0 ? agentMethods : (await getAgentDIDMethods(this.context)).map((method) => convertDidMethod(method, didPrefix));
|
|
890
|
-
} else if (!agentMethods || agentMethods.length === 0) {
|
|
891
|
-
intersection = rpMethods.dids?.map((method) => convertDidMethod(method, didPrefix));
|
|
892
|
-
} else {
|
|
893
|
-
intersection = agentMethods.filter((value) => rpMethods.dids.includes(value));
|
|
894
|
-
}
|
|
895
|
-
if (intersection.length === 0) {
|
|
896
|
-
throw Error("No matching DID methods between agent and relying party");
|
|
897
|
-
}
|
|
898
|
-
return intersection.map((value) => convertDidMethod(value, didPrefix));
|
|
899
|
-
}
|
|
900
|
-
getAgentDIDMethodsSupported(opts) {
|
|
901
|
-
const agentMethods = this.options.supportedDIDMethods?.map((method) => convertDidMethod(method, opts.didPrefix));
|
|
902
|
-
logger.debug(`agent methods: ${JSON.stringify(agentMethods)}`);
|
|
903
|
-
return agentMethods;
|
|
904
|
-
}
|
|
905
|
-
async getSubjectSyntaxTypesSupported() {
|
|
906
|
-
const authReq = await this.getAuthorizationRequest();
|
|
907
|
-
const subjectSyntaxTypesSupported = authReq.registrationMetadataPayload?.subject_syntax_types_supported;
|
|
908
|
-
return subjectSyntaxTypesSupported ?? [];
|
|
909
|
-
}
|
|
910
|
-
async getRPDIDMethodsSupported(opts) {
|
|
911
|
-
let keyType;
|
|
912
|
-
const agentMethods = (opts.agentMethods ?? this.getAgentDIDMethodsSupported(opts))?.map((method) => convertDidMethod(method, opts.didPrefix)) ?? [];
|
|
913
|
-
logger.debug(`agent methods supported: ${JSON.stringify(agentMethods)}`);
|
|
914
|
-
const authReq = await this.getAuthorizationRequest();
|
|
915
|
-
const subjectSyntaxTypesSupported = authReq.registrationMetadataPayload?.subject_syntax_types_supported?.map((method) => convertDidMethod(method, opts.didPrefix)).filter((val) => !val.startsWith("did"));
|
|
916
|
-
logger.debug(`subject syntax types supported in rp method supported: ${JSON.stringify(subjectSyntaxTypesSupported)}`);
|
|
917
|
-
const aud = await authReq.authorizationRequest.getMergedProperty("aud");
|
|
918
|
-
let rpMethods = [];
|
|
919
|
-
if (aud && aud.startsWith("did:")) {
|
|
920
|
-
const didMethod = convertDidMethod(parseDid(aud).method, opts.didPrefix);
|
|
921
|
-
logger.debug(`aud did method: ${didMethod}`);
|
|
922
|
-
if (subjectSyntaxTypesSupported && subjectSyntaxTypesSupported.length > 0 && !subjectSyntaxTypesSupported.includes("did") && !subjectSyntaxTypesSupported.includes(didMethod)) {
|
|
923
|
-
throw Error(`The aud DID method ${didMethod} is not in the supported types ${subjectSyntaxTypesSupported}`);
|
|
924
|
-
}
|
|
925
|
-
rpMethods = [
|
|
926
|
-
didMethod
|
|
927
|
-
];
|
|
928
|
-
} else if (subjectSyntaxTypesSupported) {
|
|
929
|
-
rpMethods = (Array.isArray(subjectSyntaxTypesSupported) ? subjectSyntaxTypesSupported : [
|
|
930
|
-
subjectSyntaxTypesSupported
|
|
931
|
-
]).map((method) => convertDidMethod(method, opts.didPrefix));
|
|
932
|
-
}
|
|
933
|
-
const isEBSI = rpMethods.length === 0 && (authReq.issuer?.includes(".ebsi.eu") || (await authReq.authorizationRequest.getMergedProperty("client_id"))?.includes(".ebsi.eu"));
|
|
934
|
-
let codecName = void 0;
|
|
935
|
-
if (isEBSI && (!aud || !aud.startsWith("http"))) {
|
|
936
|
-
logger.debug(`EBSI detected, adding did:key to supported DID methods for RP`);
|
|
937
|
-
const didKeyMethod = convertDidMethod("did:key", opts.didPrefix);
|
|
938
|
-
if (!agentMethods?.includes(didKeyMethod)) {
|
|
939
|
-
throw Error(`EBSI detected, but agent did not support did:key. Please reconfigure agent`);
|
|
940
|
-
}
|
|
941
|
-
rpMethods = [
|
|
942
|
-
didKeyMethod
|
|
943
|
-
];
|
|
944
|
-
keyType = "Secp256r1";
|
|
945
|
-
codecName = "jwk_jcs-pub";
|
|
946
|
-
}
|
|
947
|
-
return {
|
|
948
|
-
dids: rpMethods,
|
|
949
|
-
codecName,
|
|
950
|
-
keyType
|
|
951
|
-
};
|
|
952
|
-
}
|
|
953
|
-
async getSupportedIdentifiers(opts) {
|
|
954
|
-
const methods = await this.getSupportedDIDMethods(true);
|
|
955
|
-
logger.debug(`supported DID methods (did: prefix = true): ${JSON.stringify(methods)}`);
|
|
956
|
-
if (methods.length === 0) {
|
|
957
|
-
throw Error(`No DID methods are supported`);
|
|
958
|
-
}
|
|
959
|
-
const identifiers = await this.context.agent.didManagerFind().then((ids) => ids.filter((id) => methods.includes(id.provider)));
|
|
960
|
-
if (identifiers.length === 0) {
|
|
961
|
-
logger.debug(`No identifiers available in agent supporting methods ${JSON.stringify(methods)}`);
|
|
962
|
-
if (opts?.createInCaseNoDIDFound !== false) {
|
|
963
|
-
const { codecName, keyType } = await this.getRPDIDMethodsSupported({
|
|
964
|
-
didPrefix: true,
|
|
965
|
-
agentMethods: methods
|
|
966
|
-
});
|
|
967
|
-
const identifier = await this.context.agent.didManagerCreate({
|
|
968
|
-
provider: methods[0],
|
|
969
|
-
options: {
|
|
970
|
-
codecName,
|
|
971
|
-
keyType,
|
|
972
|
-
type: keyType
|
|
973
|
-
}
|
|
974
|
-
});
|
|
975
|
-
logger.debug(`Created a new identifier for the SIOP interaction: ${identifier.did}`);
|
|
976
|
-
identifiers.push(identifier);
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
logger.debug(`supported identifiers: ${JSON.stringify(identifiers.map((id) => id.did))}`);
|
|
980
|
-
return identifiers;
|
|
981
|
-
}
|
|
982
|
-
async getSupportedDIDs() {
|
|
983
|
-
return (await this.getSupportedIdentifiers()).map((id) => id.did);
|
|
984
|
-
}
|
|
985
|
-
async getRedirectUri() {
|
|
986
|
-
return Promise.resolve(this.verifiedAuthorizationRequest.responseURI);
|
|
987
|
-
}
|
|
988
|
-
async hasPresentationDefinitions() {
|
|
989
|
-
const defs = this._providedPresentationDefinitions ?? (await this.getAuthorizationRequest()).presentationDefinitions;
|
|
990
|
-
return defs !== void 0 && defs.length > 0;
|
|
991
|
-
}
|
|
992
|
-
async getPresentationDefinitions() {
|
|
993
|
-
if (!await this.hasPresentationDefinitions()) {
|
|
994
|
-
throw Error(`No presentation definitions found`);
|
|
995
|
-
}
|
|
996
|
-
return this._providedPresentationDefinitions ?? (await this.getAuthorizationRequest()).presentationDefinitions;
|
|
997
|
-
}
|
|
998
|
-
async getOID4VP(args) {
|
|
999
|
-
return await OID4VP.init(this, args.allIdentifiers ?? [], args.hasher);
|
|
1000
|
-
}
|
|
1001
|
-
createPresentationVerificationCallback(context) {
|
|
1002
|
-
async function presentationVerificationCallback(args, presentationSubmission) {
|
|
1003
|
-
let result;
|
|
1004
|
-
if (CredentialMapper.isSdJwtEncoded(args)) {
|
|
1005
|
-
try {
|
|
1006
|
-
const sdJwtResult = await context.agent.verifySdJwtPresentation({
|
|
1007
|
-
presentation: args
|
|
1008
|
-
});
|
|
1009
|
-
result = {
|
|
1010
|
-
verified: "header" in sdJwtResult,
|
|
1011
|
-
error: "header" in sdJwtResult ? void 0 : {
|
|
1012
|
-
message: "could not verify SD JWT presentation"
|
|
1013
|
-
}
|
|
1014
|
-
};
|
|
1015
|
-
} catch (error) {
|
|
1016
|
-
result = {
|
|
1017
|
-
verified: false,
|
|
1018
|
-
error: {
|
|
1019
|
-
message: error.message
|
|
1020
|
-
}
|
|
1021
|
-
};
|
|
1022
|
-
}
|
|
1023
|
-
} else {
|
|
1024
|
-
result = await context.agent.verifyPresentation({
|
|
1025
|
-
presentation: args
|
|
1026
|
-
});
|
|
1027
|
-
}
|
|
1028
|
-
return result;
|
|
1029
|
-
}
|
|
1030
|
-
__name(presentationVerificationCallback, "presentationVerificationCallback");
|
|
1031
|
-
return presentationVerificationCallback;
|
|
1032
|
-
}
|
|
1033
|
-
async createJarmResponseCallback({ responseOpts }) {
|
|
1034
|
-
const agent = this.context.agent;
|
|
1035
|
-
return /* @__PURE__ */ __name(async function jarmResponse(opts) {
|
|
1036
|
-
const { clientMetadata, requestObjectPayload, authorizationResponsePayload: authResponse } = opts;
|
|
1037
|
-
const jwk = await OP2.extractEncJwksFromClientMetadata(clientMetadata);
|
|
1038
|
-
const recipientKey = await agent.identifierExternalResolveByJwk({
|
|
1039
|
-
identifier: jwk
|
|
1040
|
-
});
|
|
1041
|
-
return await agent.jwtEncryptJweCompactJwt({
|
|
1042
|
-
recipientKey,
|
|
1043
|
-
protectedHeader: {},
|
|
1044
|
-
alg: requestObjectPayload.client_metadata.authorization_encrypted_response_alg ?? "ECDH-ES",
|
|
1045
|
-
enc: requestObjectPayload.client_metadata.authorization_encrypted_response_enc ?? "A256GCM",
|
|
1046
|
-
apv: encodeBase64url(opts.requestObjectPayload.nonce),
|
|
1047
|
-
apu: encodeBase64url(v4()),
|
|
1048
|
-
payload: authResponse,
|
|
1049
|
-
issuer: responseOpts.issuer,
|
|
1050
|
-
audience: responseOpts.audience
|
|
1051
|
-
}).then((result) => {
|
|
1052
|
-
return {
|
|
1053
|
-
response: result.jwt
|
|
1054
|
-
};
|
|
1055
|
-
});
|
|
1056
|
-
}, "jarmResponse");
|
|
1057
|
-
}
|
|
1058
|
-
async sendAuthorizationResponse(args) {
|
|
1059
|
-
const resolveOpts = this.options.resolveOpts ?? {
|
|
1060
|
-
resolver: getAgentResolver(this.context, {
|
|
1061
|
-
uniresolverResolution: true,
|
|
1062
|
-
localResolution: true,
|
|
1063
|
-
resolverResolution: true
|
|
1064
|
-
})
|
|
1065
|
-
};
|
|
1066
|
-
if (!resolveOpts.subjectSyntaxTypesSupported || resolveOpts.subjectSyntaxTypesSupported.length === 0) {
|
|
1067
|
-
resolveOpts.subjectSyntaxTypesSupported = await this.getSupportedDIDMethods(true);
|
|
1068
|
-
}
|
|
1069
|
-
const verification = {
|
|
1070
|
-
presentationVerificationCallback: this.createPresentationVerificationCallback(this.context)
|
|
1071
|
-
};
|
|
1072
|
-
const request = await this.getAuthorizationRequest();
|
|
1073
|
-
const hasDefinitions = await this.hasPresentationDefinitions();
|
|
1074
|
-
if (hasDefinitions) {
|
|
1075
|
-
const totalInputDescriptors = request.presentationDefinitions?.reduce((sum, pd) => {
|
|
1076
|
-
return sum + pd.definition.input_descriptors.length;
|
|
1077
|
-
}, 0);
|
|
1078
|
-
const totalVCs = args.verifiablePresentations ? this.countVCsInAllVPs(args.verifiablePresentations, args.hasher) : 0;
|
|
1079
|
-
if (!request.presentationDefinitions || !args.verifiablePresentations || totalVCs !== totalInputDescriptors) {
|
|
1080
|
-
throw Error(`Amount of presentations ${args.verifiablePresentations?.length}, doesn't match expected ${request.presentationDefinitions?.length}`);
|
|
1081
|
-
} else if (!args.presentationSubmission) {
|
|
1082
|
-
throw Error(`Presentation submission is required when verifiable presentations are required`);
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
const verifiablePresentations = args.verifiablePresentations ? args.verifiablePresentations.map((vp) => CredentialMapper.storedPresentationToOriginalFormat(vp)) : [];
|
|
1086
|
-
const op = await createOP({
|
|
1087
|
-
opOptions: {
|
|
1088
|
-
...this.options,
|
|
1089
|
-
resolveOpts: {
|
|
1090
|
-
...this.options.resolveOpts
|
|
1091
|
-
},
|
|
1092
|
-
eventEmitter: this.options.eventEmitter,
|
|
1093
|
-
presentationSignCallback: this.options.presentationSignCallback,
|
|
1094
|
-
wellknownDIDVerifyCallback: this.options.wellknownDIDVerifyCallback,
|
|
1095
|
-
supportedVersions: request.versions
|
|
1096
|
-
},
|
|
1097
|
-
idOpts: args.responseSignerOpts,
|
|
1098
|
-
context: this.context
|
|
1099
|
-
});
|
|
1100
|
-
let issuer = args.responseSignerOpts.issuer;
|
|
1101
|
-
const responseOpts = {
|
|
1102
|
-
verification,
|
|
1103
|
-
issuer,
|
|
1104
|
-
...args.isFirstParty && {
|
|
1105
|
-
isFirstParty: args.isFirstParty
|
|
1106
|
-
},
|
|
1107
|
-
...args.verifiablePresentations && {
|
|
1108
|
-
presentationExchange: {
|
|
1109
|
-
verifiablePresentations,
|
|
1110
|
-
presentationSubmission: args.presentationSubmission
|
|
1111
|
-
}
|
|
1112
|
-
},
|
|
1113
|
-
dcqlQuery: args.dcqlResponse
|
|
1114
|
-
};
|
|
1115
|
-
const authResponse = await op.createAuthorizationResponse(request, responseOpts);
|
|
1116
|
-
const response = await op.submitAuthorizationResponse(authResponse, await this.createJarmResponseCallback({
|
|
1117
|
-
responseOpts
|
|
1118
|
-
}));
|
|
1119
|
-
if (response.status >= 400) {
|
|
1120
|
-
throw Error(`Error ${response.status}: ${response.statusText || await response.text()}`);
|
|
1121
|
-
} else {
|
|
1122
|
-
return response;
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
countVCsInAllVPs(verifiablePresentations, hasher) {
|
|
1126
|
-
return verifiablePresentations.reduce((sum, vp) => {
|
|
1127
|
-
if (CredentialMapper.isMsoMdocDecodedPresentation(vp) || CredentialMapper.isMsoMdocOid4VPEncoded(vp)) {
|
|
1128
|
-
return sum + 1;
|
|
1129
|
-
}
|
|
1130
|
-
const uvp = CredentialMapper.toUniformPresentation(vp, {
|
|
1131
|
-
hasher: hasher ?? this.options.hasher
|
|
1132
|
-
});
|
|
1133
|
-
if (uvp.verifiableCredential?.length) {
|
|
1134
|
-
return sum + uvp.verifiableCredential?.length;
|
|
1135
|
-
}
|
|
1136
|
-
const isSdJWT = CredentialMapper.isSdJwtDecodedCredential(uvp);
|
|
1137
|
-
if (isSdJWT || uvp.verifiableCredential && !PEX.allowMultipleVCsPerPresentation(uvp.verifiableCredential)) {
|
|
1138
|
-
return sum + 1;
|
|
1139
|
-
}
|
|
1140
|
-
return sum;
|
|
1141
|
-
}, 0);
|
|
1142
|
-
}
|
|
1143
|
-
};
|
|
1144
|
-
function convertDidMethod(didMethod, didPrefix) {
|
|
1145
|
-
if (didPrefix === false) {
|
|
1146
|
-
return didMethod.startsWith("did:") ? didMethod.toLowerCase().replace("did:", "") : didMethod.toLowerCase();
|
|
1147
|
-
}
|
|
1148
|
-
return didMethod.startsWith("did:") ? didMethod.toLowerCase() : `did:${didMethod.toLowerCase().replace("did:", "")}`;
|
|
1149
|
-
}
|
|
1150
|
-
__name(convertDidMethod, "convertDidMethod");
|
|
1151
|
-
|
|
1152
|
-
// src/agent/DidAuthSiopOpAuthenticator.ts
|
|
1153
|
-
import { PEX as PEX3, Status as Status2 } from "@sphereon/pex";
|
|
1154
|
-
import { computeEntryHash } from "@veramo/utils";
|
|
1155
|
-
import { DcqlQuery as DcqlQuery2 } from "dcql";
|
|
1156
|
-
|
|
1157
|
-
// src/machine/Siopv2Machine.ts
|
|
1158
|
-
import { assign, createMachine, interpret } from "xstate";
|
|
1159
|
-
|
|
1160
|
-
// src/localization/Localization.ts
|
|
1161
|
-
import i18n from "i18n-js";
|
|
1162
|
-
import memoize from "lodash.memoize";
|
|
1163
|
-
var Localization = class Localization2 {
|
|
1164
|
-
static {
|
|
1165
|
-
__name(this, "Localization");
|
|
1166
|
-
}
|
|
1167
|
-
static translationGetters = {
|
|
1168
|
-
[SupportedLanguage.ENGLISH]: () => require_en(),
|
|
1169
|
-
[SupportedLanguage.DUTCH]: () => require_nl()
|
|
1170
|
-
};
|
|
1171
|
-
static translate = memoize((key, config) => {
|
|
1172
|
-
if (Object.keys(i18n.translations).length === 0) {
|
|
1173
|
-
i18n.translations = {
|
|
1174
|
-
[SupportedLanguage.ENGLISH]: Localization2.translationGetters[SupportedLanguage.ENGLISH]()
|
|
1175
|
-
};
|
|
1176
|
-
i18n.locale = SupportedLanguage.ENGLISH;
|
|
1177
|
-
} else {
|
|
1178
|
-
i18n.translations = {
|
|
1179
|
-
[i18n.locale]: {
|
|
1180
|
-
...i18n.translations[i18n.locale],
|
|
1181
|
-
...Localization2.translationGetters[this.findSupportedLanguage(i18n.locale) || SupportedLanguage.ENGLISH]()
|
|
1182
|
-
}
|
|
1183
|
-
};
|
|
1184
|
-
}
|
|
1185
|
-
return i18n.t(key, config);
|
|
1186
|
-
}, (key, config) => config ? key + JSON.stringify(config) : key);
|
|
1187
|
-
static findSupportedLanguage = /* @__PURE__ */ __name((locale) => {
|
|
1188
|
-
for (const language of Object.values(SupportedLanguage)) {
|
|
1189
|
-
if (language === locale) {
|
|
1190
|
-
return language;
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
return void 0;
|
|
1194
|
-
}, "findSupportedLanguage");
|
|
1195
|
-
static getLocale = /* @__PURE__ */ __name(() => {
|
|
1196
|
-
return i18n.locale || SupportedLanguage.ENGLISH;
|
|
1197
|
-
}, "getLocale");
|
|
1198
|
-
};
|
|
1199
|
-
var translate = Localization.translate;
|
|
1200
|
-
|
|
1201
|
-
// src/machine/Siopv2Machine.ts
|
|
1202
|
-
import { Loggers as Loggers2 } from "@sphereon/ssi-types";
|
|
1203
|
-
var logger2 = Loggers2.DEFAULT.get(LOGGER_NAMESPACE);
|
|
1204
|
-
var Siopv2HasNoContactGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
1205
|
-
const { contact } = _ctx;
|
|
1206
|
-
return contact === void 0;
|
|
1207
|
-
}, "Siopv2HasNoContactGuard");
|
|
1208
|
-
var Siopv2HasContactGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
1209
|
-
const { contact } = _ctx;
|
|
1210
|
-
return contact !== void 0;
|
|
1211
|
-
}, "Siopv2HasContactGuard");
|
|
1212
|
-
var Siopv2HasAuthorizationRequestGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
1213
|
-
const { authorizationRequestData } = _ctx;
|
|
1214
|
-
return authorizationRequestData !== void 0;
|
|
1215
|
-
}, "Siopv2HasAuthorizationRequestGuard");
|
|
1216
|
-
var Siopv2HasSelectableCredentialsAndContactGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
1217
|
-
const { authorizationRequestData, contact } = _ctx;
|
|
1218
|
-
if (!authorizationRequestData) {
|
|
1219
|
-
throw new Error("Missing authorization request data in context");
|
|
1220
|
-
}
|
|
1221
|
-
if (!contact) {
|
|
1222
|
-
throw new Error("Missing contact request data in context");
|
|
1223
|
-
}
|
|
1224
|
-
return authorizationRequestData.presentationDefinitions !== void 0;
|
|
1225
|
-
}, "Siopv2HasSelectableCredentialsAndContactGuard");
|
|
1226
|
-
var Siopv2CreateContactGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
1227
|
-
const { contactAlias, hasContactConsent } = _ctx;
|
|
1228
|
-
return hasContactConsent && contactAlias !== void 0 && contactAlias.length > 0;
|
|
1229
|
-
}, "Siopv2CreateContactGuard");
|
|
1230
|
-
var Siopv2HasSelectedRequiredCredentialsGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
1231
|
-
const { authorizationRequestData } = _ctx;
|
|
1232
|
-
if (authorizationRequestData === void 0) {
|
|
1233
|
-
throw new Error("Missing authorization request data in context");
|
|
1234
|
-
}
|
|
1235
|
-
if (authorizationRequestData.presentationDefinitions === void 0 || authorizationRequestData.presentationDefinitions.length === 0) {
|
|
1236
|
-
throw Error("No presentation definitions present");
|
|
1237
|
-
}
|
|
1238
|
-
return _ctx.selectedCredentials.length > 0;
|
|
1239
|
-
}, "Siopv2HasSelectedRequiredCredentialsGuard");
|
|
1240
|
-
var Siopv2IsSiopOnlyGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
1241
|
-
const { authorizationRequestData } = _ctx;
|
|
1242
|
-
if (authorizationRequestData === void 0) {
|
|
1243
|
-
throw new Error("Missing authorization request data in context");
|
|
1244
|
-
}
|
|
1245
|
-
return authorizationRequestData.presentationDefinitions === void 0;
|
|
1246
|
-
}, "Siopv2IsSiopOnlyGuard");
|
|
1247
|
-
var Siopv2IsSiopWithOID4VPGuard = /* @__PURE__ */ __name((_ctx, _event) => {
|
|
1248
|
-
const { authorizationRequestData, selectableCredentialsMap } = _ctx;
|
|
1249
|
-
if (!authorizationRequestData) {
|
|
1250
|
-
throw new Error("Missing authorization request data in context");
|
|
1251
|
-
}
|
|
1252
|
-
if (!selectableCredentialsMap) {
|
|
1253
|
-
throw new Error("Missing selectableCredentialsMap in context");
|
|
1254
|
-
}
|
|
1255
|
-
return authorizationRequestData.presentationDefinitions !== void 0;
|
|
548
|
+
return authorizationRequestData.dcqlQuery !== void 0;
|
|
1256
549
|
}, "Siopv2IsSiopWithOID4VPGuard");
|
|
1257
550
|
var createSiopv2Machine = /* @__PURE__ */ __name((opts) => {
|
|
1258
551
|
const { url, idOpts: idOpts2 } = opts;
|
|
@@ -1524,432 +817,701 @@ var createSiopv2Machine = /* @__PURE__ */ __name((opts) => {
|
|
|
1524
817
|
}
|
|
1525
818
|
}
|
|
1526
819
|
});
|
|
1527
|
-
}, "createSiopv2Machine");
|
|
1528
|
-
var Siopv2Machine = class {
|
|
1529
|
-
static {
|
|
1530
|
-
__name(this, "Siopv2Machine");
|
|
1531
|
-
}
|
|
1532
|
-
static newInstance(opts) {
|
|
1533
|
-
|
|
1534
|
-
const interpreter = interpret(createSiopv2Machine(opts).withConfig({
|
|
1535
|
-
services: {
|
|
1536
|
-
...opts?.services
|
|
1537
|
-
},
|
|
1538
|
-
guards: {
|
|
1539
|
-
Siopv2HasNoContactGuard,
|
|
1540
|
-
Siopv2HasContactGuard,
|
|
1541
|
-
Siopv2HasAuthorizationRequestGuard,
|
|
1542
|
-
Siopv2HasSelectableCredentialsAndContactGuard,
|
|
1543
|
-
Siopv2HasSelectedRequiredCredentialsGuard,
|
|
1544
|
-
Siopv2IsSiopOnlyGuard,
|
|
1545
|
-
Siopv2IsSiopWithOID4VPGuard,
|
|
1546
|
-
Siopv2CreateContactGuard,
|
|
1547
|
-
...opts?.guards
|
|
1548
|
-
}
|
|
1549
|
-
}));
|
|
1550
|
-
if (typeof opts?.subscription === "function") {
|
|
1551
|
-
interpreter.onTransition(opts.subscription);
|
|
1552
|
-
}
|
|
1553
|
-
if (opts?.requireCustomNavigationHook !== true) {
|
|
1554
|
-
interpreter.onTransition((snapshot) => {
|
|
1555
|
-
if (opts.stateNavigationListener !== void 0) {
|
|
1556
|
-
void opts.stateNavigationListener(interpreter, snapshot);
|
|
1557
|
-
}
|
|
1558
|
-
});
|
|
1559
|
-
}
|
|
1560
|
-
interpreter.onTransition((snapshot) => {
|
|
1561
|
-
|
|
820
|
+
}, "createSiopv2Machine");
|
|
821
|
+
var Siopv2Machine = class {
|
|
822
|
+
static {
|
|
823
|
+
__name(this, "Siopv2Machine");
|
|
824
|
+
}
|
|
825
|
+
static newInstance(opts) {
|
|
826
|
+
logger.info("New Siopv2Machine instance");
|
|
827
|
+
const interpreter = interpret(createSiopv2Machine(opts).withConfig({
|
|
828
|
+
services: {
|
|
829
|
+
...opts?.services
|
|
830
|
+
},
|
|
831
|
+
guards: {
|
|
832
|
+
Siopv2HasNoContactGuard,
|
|
833
|
+
Siopv2HasContactGuard,
|
|
834
|
+
Siopv2HasAuthorizationRequestGuard,
|
|
835
|
+
Siopv2HasSelectableCredentialsAndContactGuard,
|
|
836
|
+
Siopv2HasSelectedRequiredCredentialsGuard,
|
|
837
|
+
Siopv2IsSiopOnlyGuard,
|
|
838
|
+
Siopv2IsSiopWithOID4VPGuard,
|
|
839
|
+
Siopv2CreateContactGuard,
|
|
840
|
+
...opts?.guards
|
|
841
|
+
}
|
|
842
|
+
}));
|
|
843
|
+
if (typeof opts?.subscription === "function") {
|
|
844
|
+
interpreter.onTransition(opts.subscription);
|
|
845
|
+
}
|
|
846
|
+
if (opts?.requireCustomNavigationHook !== true) {
|
|
847
|
+
interpreter.onTransition((snapshot) => {
|
|
848
|
+
if (opts.stateNavigationListener !== void 0) {
|
|
849
|
+
void opts.stateNavigationListener(interpreter, snapshot);
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
interpreter.onTransition((snapshot) => {
|
|
854
|
+
logger.info("onTransition to new state", snapshot.value);
|
|
855
|
+
});
|
|
856
|
+
return {
|
|
857
|
+
interpreter
|
|
858
|
+
};
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
|
|
862
|
+
// src/services/Siopv2MachineService.ts
|
|
863
|
+
import { SupportedVersion } from "@sphereon/did-auth-siop";
|
|
864
|
+
import { isOID4VCIssuerIdentifier } from "@sphereon/ssi-sdk-ext.identifier-resolution";
|
|
865
|
+
import { verifiableCredentialForRoleFilter } from "@sphereon/ssi-sdk.credential-store";
|
|
866
|
+
import { ConnectionType, CredentialRole } from "@sphereon/ssi-sdk.data-store";
|
|
867
|
+
import { CredentialMapper as CredentialMapper3, Loggers as Loggers2 } from "@sphereon/ssi-types";
|
|
868
|
+
import { encodeJoseBlob } from "@sphereon/ssi-sdk.core";
|
|
869
|
+
import { DcqlPresentation, DcqlQuery } from "dcql";
|
|
870
|
+
|
|
871
|
+
// src/utils/dcql.ts
|
|
872
|
+
import { CredentialMapper as CredentialMapper2 } from "@sphereon/ssi-types";
|
|
873
|
+
import { Dcql } from "@sphereon/did-auth-siop";
|
|
874
|
+
|
|
875
|
+
// src/utils/CredentialUtils.ts
|
|
876
|
+
import { CredentialMapper } from "@sphereon/ssi-types";
|
|
877
|
+
var isUniqueDigitalCredential = /* @__PURE__ */ __name((credential) => {
|
|
878
|
+
return credential.digitalCredential !== void 0;
|
|
879
|
+
}, "isUniqueDigitalCredential");
|
|
880
|
+
|
|
881
|
+
// src/utils/dcql.ts
|
|
882
|
+
function convertToDcqlCredentials(credential, hasher) {
|
|
883
|
+
let originalVerifiableCredential;
|
|
884
|
+
if (isUniqueDigitalCredential(credential)) {
|
|
885
|
+
if (!credential.originalVerifiableCredential) {
|
|
886
|
+
throw new Error("originalVerifiableCredential is not defined in UniqueDigitalCredential");
|
|
887
|
+
}
|
|
888
|
+
originalVerifiableCredential = CredentialMapper2.decodeVerifiableCredential(credential.originalVerifiableCredential, hasher);
|
|
889
|
+
} else {
|
|
890
|
+
originalVerifiableCredential = CredentialMapper2.decodeVerifiableCredential(credential, hasher);
|
|
891
|
+
}
|
|
892
|
+
if (!originalVerifiableCredential) {
|
|
893
|
+
throw new Error("No payload found");
|
|
894
|
+
}
|
|
895
|
+
if (CredentialMapper2.isJwtDecodedCredential(originalVerifiableCredential)) {
|
|
896
|
+
return Dcql.toDcqlJwtCredential(CredentialMapper2.toWrappedVerifiableCredential(originalVerifiableCredential));
|
|
897
|
+
} else if (CredentialMapper2.isSdJwtDecodedCredential(originalVerifiableCredential)) {
|
|
898
|
+
return Dcql.toDcqlSdJwtCredential(CredentialMapper2.toWrappedVerifiableCredential(originalVerifiableCredential));
|
|
899
|
+
} else if (CredentialMapper2.isMsoMdocDecodedCredential(originalVerifiableCredential)) {
|
|
900
|
+
return Dcql.toDcqlMdocCredential(CredentialMapper2.toWrappedVerifiableCredential(originalVerifiableCredential));
|
|
901
|
+
} else if (CredentialMapper2.isW3cCredential(originalVerifiableCredential)) {
|
|
902
|
+
return Dcql.toDcqlJsonLdCredential(CredentialMapper2.toWrappedVerifiableCredential(originalVerifiableCredential));
|
|
903
|
+
}
|
|
904
|
+
throw Error(`Unable to map credential to DCQL credential. Credential: ${JSON.stringify(originalVerifiableCredential)}`);
|
|
905
|
+
}
|
|
906
|
+
__name(convertToDcqlCredentials, "convertToDcqlCredentials");
|
|
907
|
+
|
|
908
|
+
// src/services/Siopv2MachineService.ts
|
|
909
|
+
import { getOrCreatePrimaryIdentifier, SupportedDidMethodEnum } from "@sphereon/ssi-sdk-ext.did-utils";
|
|
910
|
+
var logger2 = Loggers2.DEFAULT.get(LOGGER_NAMESPACE);
|
|
911
|
+
var siopSendAuthorizationResponse = /* @__PURE__ */ __name(async (connectionType, args, context) => {
|
|
912
|
+
const { agent } = context;
|
|
913
|
+
const { credentials } = args;
|
|
914
|
+
if (connectionType !== ConnectionType.SIOPv2_OpenID4VP) {
|
|
915
|
+
return Promise.reject(Error(`No supported authentication provider for type: ${connectionType}`));
|
|
916
|
+
}
|
|
917
|
+
const session = await agent.siopGetOPSession({
|
|
918
|
+
sessionId: args.sessionId
|
|
919
|
+
});
|
|
920
|
+
const request = await session.getAuthorizationRequest();
|
|
921
|
+
const aud = request.authorizationRequest.getMergedProperty("aud");
|
|
922
|
+
logger2.debug(`AUD: ${aud}`);
|
|
923
|
+
logger2.debug(JSON.stringify(request.authorizationRequest));
|
|
924
|
+
const domain = await request.authorizationRequest.getMergedProperty("client_id") ?? request.issuer ?? (request.versions.includes(SupportedVersion.JWT_VC_PRESENTATION_PROFILE_v1) ? "https://self-issued.me/v2/openid-vc" : "https://self-issued.me/v2");
|
|
925
|
+
logger2.debug(`NONCE: ${session.nonce}, domain: ${domain}`);
|
|
926
|
+
const firstUniqueDC = credentials[0];
|
|
927
|
+
if (typeof firstUniqueDC !== "object" || !("digitalCredential" in firstUniqueDC)) {
|
|
928
|
+
return Promise.reject(Error("SiopMachine only supports UniqueDigitalCredentials for now"));
|
|
929
|
+
}
|
|
930
|
+
let identifier;
|
|
931
|
+
const digitalCredential = firstUniqueDC.digitalCredential;
|
|
932
|
+
const firstVC = firstUniqueDC.uniformVerifiableCredential;
|
|
933
|
+
const holder = CredentialMapper3.isSdJwtDecodedCredential(firstVC) ? firstVC.decodedPayload.cnf?.jwk ? (
|
|
934
|
+
//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
|
|
935
|
+
`did:jwk:${encodeJoseBlob(firstVC.decodedPayload.cnf?.jwk)}#0`
|
|
936
|
+
) : firstVC.decodedPayload.sub : Array.isArray(firstVC.credentialSubject) ? firstVC.credentialSubject[0].id : firstVC.credentialSubject.id;
|
|
937
|
+
if (!digitalCredential.kmsKeyRef) {
|
|
938
|
+
if (!holder) {
|
|
939
|
+
return Promise.reject(`No holder found and no kmsKeyRef in DB. Cannot determine identifier to use`);
|
|
940
|
+
}
|
|
941
|
+
try {
|
|
942
|
+
identifier = await session.context.agent.identifierManagedGet({
|
|
943
|
+
identifier: holder
|
|
944
|
+
});
|
|
945
|
+
} catch (e) {
|
|
946
|
+
logger2.debug(`Holder DID not found: ${holder}`);
|
|
947
|
+
throw e;
|
|
948
|
+
}
|
|
949
|
+
} else if (isOID4VCIssuerIdentifier(digitalCredential.kmsKeyRef)) {
|
|
950
|
+
identifier = await session.context.agent.identifierManagedGetByOID4VCIssuer({
|
|
951
|
+
identifier: firstUniqueDC.digitalCredential.kmsKeyRef
|
|
952
|
+
});
|
|
953
|
+
} else {
|
|
954
|
+
switch (digitalCredential.subjectCorrelationType) {
|
|
955
|
+
case "DID":
|
|
956
|
+
identifier = await session.context.agent.identifierManagedGetByDid({
|
|
957
|
+
identifier: digitalCredential.subjectCorrelationId ?? holder,
|
|
958
|
+
kmsKeyRef: digitalCredential.kmsKeyRef
|
|
959
|
+
});
|
|
960
|
+
break;
|
|
961
|
+
// TODO other implementations?
|
|
962
|
+
default:
|
|
963
|
+
identifier = await session.context.agent.identifierManagedGetByKid({
|
|
964
|
+
identifier: digitalCredential.subjectCorrelationId ?? holder ?? digitalCredential.kmsKeyRef,
|
|
965
|
+
kmsKeyRef: digitalCredential.kmsKeyRef
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
const dcqlCredentialsWithCredentials = new Map(credentials.map((vc) => [
|
|
970
|
+
convertToDcqlCredentials(vc),
|
|
971
|
+
vc
|
|
972
|
+
]));
|
|
973
|
+
const queryResult = DcqlQuery.query(request.dcqlQuery, Array.from(dcqlCredentialsWithCredentials.keys()));
|
|
974
|
+
if (!queryResult.can_be_satisfied) {
|
|
975
|
+
return Promise.reject(Error("Credentials do not match required query request"));
|
|
976
|
+
}
|
|
977
|
+
const presentation = {};
|
|
978
|
+
const uniqueCredentials = Array.from(dcqlCredentialsWithCredentials.values());
|
|
979
|
+
for (const [key, value] of Object.entries(queryResult.credential_matches)) {
|
|
980
|
+
if (value.success) {
|
|
981
|
+
const matchedCredentials = value.valid_credentials.map((cred) => uniqueCredentials[cred.input_credential_index]);
|
|
982
|
+
const vc = matchedCredentials[0];
|
|
983
|
+
if (!vc) {
|
|
984
|
+
continue;
|
|
985
|
+
}
|
|
986
|
+
const originalVc = retrieveEncodedCredential(vc);
|
|
987
|
+
if (!originalVc) {
|
|
988
|
+
continue;
|
|
989
|
+
}
|
|
990
|
+
if (originalVc) {
|
|
991
|
+
presentation[key] = originalVc;
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
const dcqlPresentation = DcqlPresentation.parse(presentation);
|
|
996
|
+
const response = session.sendAuthorizationResponse({
|
|
997
|
+
responseSignerOpts: identifier,
|
|
998
|
+
dcqlResponse: {
|
|
999
|
+
dcqlPresentation
|
|
1000
|
+
}
|
|
1001
|
+
});
|
|
1002
|
+
logger2.debug(`Response: `, response);
|
|
1003
|
+
return response;
|
|
1004
|
+
}, "siopSendAuthorizationResponse");
|
|
1005
|
+
var retrieveEncodedCredential = /* @__PURE__ */ __name((credential) => {
|
|
1006
|
+
return credential.originalVerifiableCredential !== void 0 && credential.originalVerifiableCredential !== null && credential?.originalVerifiableCredential?.compactSdJwtVc !== void 0 && credential?.originalVerifiableCredential?.compactSdJwtVc !== null ? credential.originalVerifiableCredential.compactSdJwtVc : credential.originalVerifiableCredential;
|
|
1007
|
+
}, "retrieveEncodedCredential");
|
|
1008
|
+
var getSelectableCredentials = /* @__PURE__ */ __name(async (dcqlQuery, context) => {
|
|
1009
|
+
const agentContext = {
|
|
1010
|
+
...context,
|
|
1011
|
+
agent: context.agent
|
|
1012
|
+
};
|
|
1013
|
+
const { agent } = agentContext;
|
|
1014
|
+
const uniqueVerifiableCredentials = await agent.crsGetUniqueCredentials({
|
|
1015
|
+
filter: verifiableCredentialForRoleFilter(CredentialRole.HOLDER)
|
|
1016
|
+
});
|
|
1017
|
+
const branding = await agent.ibGetCredentialBranding();
|
|
1018
|
+
const dcqlCredentialsWithCredentials = new Map(uniqueVerifiableCredentials.map((vc) => [
|
|
1019
|
+
convertToDcqlCredentials(vc),
|
|
1020
|
+
vc
|
|
1021
|
+
]));
|
|
1022
|
+
const queryResult = DcqlQuery.query(dcqlQuery, Array.from(dcqlCredentialsWithCredentials.keys()));
|
|
1023
|
+
const uniqueCredentials = Array.from(dcqlCredentialsWithCredentials.values());
|
|
1024
|
+
const selectableCredentialsMap = /* @__PURE__ */ new Map();
|
|
1025
|
+
for (const [key, value] of Object.entries(queryResult.credential_matches)) {
|
|
1026
|
+
if (!value.valid_credentials) {
|
|
1027
|
+
continue;
|
|
1028
|
+
}
|
|
1029
|
+
const mapSelectableCredentialPromises = value.valid_credentials.map(async (cred) => {
|
|
1030
|
+
const matchedCredential = uniqueCredentials[cred.input_credential_index];
|
|
1031
|
+
const credentialBranding = branding.filter((cb) => cb.vcHash === matchedCredential.hash);
|
|
1032
|
+
const issuerPartyIdentity = await agent.cmGetContacts({
|
|
1033
|
+
filter: [
|
|
1034
|
+
{
|
|
1035
|
+
identities: {
|
|
1036
|
+
identifier: {
|
|
1037
|
+
correlationId: matchedCredential.uniformVerifiableCredential.issuerDid
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
]
|
|
1042
|
+
});
|
|
1043
|
+
const subjectPartyIdentity = await agent.cmGetContacts({
|
|
1044
|
+
filter: [
|
|
1045
|
+
{
|
|
1046
|
+
identities: {
|
|
1047
|
+
identifier: {
|
|
1048
|
+
correlationId: matchedCredential.uniformVerifiableCredential.subjectDid
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
]
|
|
1053
|
+
});
|
|
1054
|
+
return {
|
|
1055
|
+
credential: matchedCredential,
|
|
1056
|
+
credentialBranding: credentialBranding[0]?.localeBranding,
|
|
1057
|
+
issuerParty: issuerPartyIdentity?.[0],
|
|
1058
|
+
subjectParty: subjectPartyIdentity?.[0]
|
|
1059
|
+
};
|
|
1060
|
+
});
|
|
1061
|
+
const selectableCredentials = await Promise.all(mapSelectableCredentialPromises);
|
|
1062
|
+
selectableCredentialsMap.set(key, selectableCredentials);
|
|
1063
|
+
}
|
|
1064
|
+
return selectableCredentialsMap;
|
|
1065
|
+
}, "getSelectableCredentials");
|
|
1066
|
+
var translateCorrelationIdToName = /* @__PURE__ */ __name(async (correlationId, context) => {
|
|
1067
|
+
const { agent } = context;
|
|
1068
|
+
const contacts = await agent.cmGetContacts({
|
|
1069
|
+
filter: [
|
|
1070
|
+
{
|
|
1071
|
+
identities: {
|
|
1072
|
+
identifier: {
|
|
1073
|
+
correlationId
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
]
|
|
1078
|
+
});
|
|
1079
|
+
if (contacts.length === 0) {
|
|
1080
|
+
return void 0;
|
|
1081
|
+
}
|
|
1082
|
+
return contacts[0].contact.displayName;
|
|
1083
|
+
}, "translateCorrelationIdToName");
|
|
1084
|
+
|
|
1085
|
+
// src/session/functions.ts
|
|
1086
|
+
import { OP, PassBy, ResponseMode, SupportedVersion as SupportedVersion2 } from "@sphereon/did-auth-siop";
|
|
1087
|
+
import { SigningAlgo } from "@sphereon/oid4vc-common";
|
|
1088
|
+
import { isManagedIdentifierDidOpts, isManagedIdentifierX5cOpts } from "@sphereon/ssi-sdk-ext.identifier-resolution";
|
|
1089
|
+
import { createPEXPresentationSignCallback } from "@sphereon/ssi-sdk.presentation-exchange";
|
|
1090
|
+
import { EventEmitter } from "events";
|
|
1091
|
+
async function createOID4VPPresentationSignCallback({ presentationSignCallback, idOpts: idOpts1, domain, fetchRemoteContexts, challenge, format, context, skipDidResolution }) {
|
|
1092
|
+
if (typeof presentationSignCallback === "function") {
|
|
1093
|
+
return presentationSignCallback;
|
|
1094
|
+
}
|
|
1095
|
+
return createPEXPresentationSignCallback({
|
|
1096
|
+
idOpts: idOpts1,
|
|
1097
|
+
fetchRemoteContexts,
|
|
1098
|
+
domain,
|
|
1099
|
+
challenge,
|
|
1100
|
+
format,
|
|
1101
|
+
skipDidResolution
|
|
1102
|
+
}, context);
|
|
1103
|
+
}
|
|
1104
|
+
__name(createOID4VPPresentationSignCallback, "createOID4VPPresentationSignCallback");
|
|
1105
|
+
async function createOPBuilder({ opOptions, idOpts: idOpts1, context }) {
|
|
1106
|
+
const eventEmitter = opOptions.eventEmitter ?? new EventEmitter();
|
|
1107
|
+
const builder = OP.builder().withResponseMode(opOptions.responseMode ?? ResponseMode.DIRECT_POST).withSupportedVersions(opOptions.supportedVersions ?? [
|
|
1108
|
+
SupportedVersion2.SIOPv2_ID1,
|
|
1109
|
+
SupportedVersion2.JWT_VC_PRESENTATION_PROFILE_v1,
|
|
1110
|
+
SupportedVersion2.SIOPv2_D11,
|
|
1111
|
+
SupportedVersion2.SIOPv2_D12_OID4VP_D18
|
|
1112
|
+
]).withExpiresIn(opOptions.expiresIn ?? 300).withEventEmitter(eventEmitter).withRegistration({
|
|
1113
|
+
passBy: PassBy.VALUE
|
|
1114
|
+
});
|
|
1115
|
+
const wellknownDIDVerifyCallback = opOptions.wellknownDIDVerifyCallback ? opOptions.wellknownDIDVerifyCallback : async (args) => {
|
|
1116
|
+
const result = await context.agent.cvVerifyCredential({
|
|
1117
|
+
credential: args.credential,
|
|
1118
|
+
fetchRemoteContexts: true
|
|
1562
1119
|
});
|
|
1563
1120
|
return {
|
|
1564
|
-
|
|
1121
|
+
verified: result.result
|
|
1565
1122
|
};
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
import { PEX as PEX2 } from "@sphereon/pex";
|
|
1572
|
-
import { isOID4VCIssuerIdentifier as isOID4VCIssuerIdentifier2 } from "@sphereon/ssi-sdk-ext.identifier-resolution";
|
|
1573
|
-
import { verifiableCredentialForRoleFilter as verifiableCredentialForRoleFilter2 } from "@sphereon/ssi-sdk.credential-store";
|
|
1574
|
-
import { ConnectionType, CredentialRole } from "@sphereon/ssi-sdk.data-store";
|
|
1575
|
-
import { CredentialMapper as CredentialMapper4, Loggers as Loggers3 } from "@sphereon/ssi-types";
|
|
1576
|
-
import { getOrCreatePrimaryIdentifier, SupportedDidMethodEnum } from "@sphereon/ssi-sdk-ext.did-utils";
|
|
1577
|
-
import { defaultHasher as defaultHasher2, encodeJoseBlob } from "@sphereon/ssi-sdk.core";
|
|
1578
|
-
import { DcqlPresentation, DcqlQuery } from "dcql";
|
|
1579
|
-
|
|
1580
|
-
// src/utils/dcql.ts
|
|
1581
|
-
import { CredentialMapper as CredentialMapper3 } from "@sphereon/ssi-types";
|
|
1582
|
-
|
|
1583
|
-
// src/utils/CredentialUtils.ts
|
|
1584
|
-
import { CredentialMapper as CredentialMapper2 } from "@sphereon/ssi-types";
|
|
1585
|
-
var getOriginalVerifiableCredential = /* @__PURE__ */ __name((credential) => {
|
|
1586
|
-
if (isUniqueDigitalCredential(credential)) {
|
|
1587
|
-
if (!credential.originalVerifiableCredential) {
|
|
1588
|
-
throw new Error("originalVerifiableCredential is not defined in UniqueDigitalCredential");
|
|
1123
|
+
};
|
|
1124
|
+
builder.withVerifyJwtCallback(opOptions.verifyJwtCallback ? opOptions.verifyJwtCallback : getVerifyJwtCallback({
|
|
1125
|
+
verifyOpts: {
|
|
1126
|
+
wellknownDIDVerifyCallback,
|
|
1127
|
+
checkLinkedDomain: "if_present"
|
|
1589
1128
|
}
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
var getCredentialFromProofOrWrapped = /* @__PURE__ */ __name((cred, hasher) => {
|
|
1595
|
-
if (typeof cred === "object" && "proof" in cred && "jwt" in cred.proof && CredentialMapper2.isSdJwtEncoded(cred.proof.jwt)) {
|
|
1596
|
-
return cred.proof.jwt;
|
|
1597
|
-
}
|
|
1598
|
-
return CredentialMapper2.toWrappedVerifiableCredential(cred, {
|
|
1599
|
-
hasher
|
|
1600
|
-
}).original;
|
|
1601
|
-
}, "getCredentialFromProofOrWrapped");
|
|
1602
|
-
var isUniqueDigitalCredential = /* @__PURE__ */ __name((credential) => {
|
|
1603
|
-
return credential.digitalCredential !== void 0;
|
|
1604
|
-
}, "isUniqueDigitalCredential");
|
|
1605
|
-
|
|
1606
|
-
// src/utils/dcql.ts
|
|
1607
|
-
function convertToDcqlCredentials(credential, hasher) {
|
|
1608
|
-
let payload;
|
|
1609
|
-
if (isUniqueDigitalCredential(credential)) {
|
|
1610
|
-
if (!credential.originalVerifiableCredential) {
|
|
1611
|
-
throw new Error("originalVerifiableCredential is not defined in UniqueDigitalCredential");
|
|
1129
|
+
}, context));
|
|
1130
|
+
if (idOpts1) {
|
|
1131
|
+
if (opOptions.skipDidResolution && isManagedIdentifierDidOpts(idOpts1)) {
|
|
1132
|
+
idOpts1.offlineWhenNoDIDRegistered = true;
|
|
1612
1133
|
}
|
|
1613
|
-
|
|
1134
|
+
const createJwtCallback = createJwtCallbackWithIdOpts(idOpts1, context);
|
|
1135
|
+
builder.withCreateJwtCallback(createJwtCallback);
|
|
1136
|
+
builder.withPresentationSignCallback(await createOID4VPPresentationSignCallback({
|
|
1137
|
+
presentationSignCallback: opOptions.presentationSignCallback,
|
|
1138
|
+
skipDidResolution: opOptions.skipDidResolution ?? false,
|
|
1139
|
+
idOpts: idOpts1,
|
|
1140
|
+
context
|
|
1141
|
+
}));
|
|
1614
1142
|
} else {
|
|
1615
|
-
|
|
1143
|
+
const createJwtCallback = createJwtCallbackWithOpOpts(opOptions, context);
|
|
1144
|
+
builder.withCreateJwtCallback(createJwtCallback);
|
|
1616
1145
|
}
|
|
1617
|
-
|
|
1618
|
-
|
|
1146
|
+
return builder;
|
|
1147
|
+
}
|
|
1148
|
+
__name(createOPBuilder, "createOPBuilder");
|
|
1149
|
+
function createJwtCallbackWithIdOpts(idOpts1, context) {
|
|
1150
|
+
return async (jwtIssuer, jwt) => {
|
|
1151
|
+
let issuer;
|
|
1152
|
+
if (isManagedIdentifierDidOpts(idOpts1)) {
|
|
1153
|
+
issuer = {
|
|
1154
|
+
...idOpts1,
|
|
1155
|
+
method: idOpts1.method,
|
|
1156
|
+
noIdentifierInHeader: false
|
|
1157
|
+
};
|
|
1158
|
+
} else if (isManagedIdentifierX5cOpts(idOpts1)) {
|
|
1159
|
+
issuer = {
|
|
1160
|
+
...idOpts1,
|
|
1161
|
+
method: idOpts1.method,
|
|
1162
|
+
noIdentifierInHeader: false
|
|
1163
|
+
};
|
|
1164
|
+
} else {
|
|
1165
|
+
return Promise.reject(Error(`JWT issuer method ${jwtIssuer.method} not yet supported`));
|
|
1166
|
+
}
|
|
1167
|
+
const result = await context.agent.jwtCreateJwsCompactSignature({
|
|
1168
|
+
issuer,
|
|
1169
|
+
protectedHeader: jwt.header,
|
|
1170
|
+
payload: jwt.payload
|
|
1171
|
+
});
|
|
1172
|
+
return result.jwt;
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
__name(createJwtCallbackWithIdOpts, "createJwtCallbackWithIdOpts");
|
|
1176
|
+
function createJwtCallbackWithOpOpts(opOpts, context) {
|
|
1177
|
+
return async (jwtIssuer, jwt) => {
|
|
1178
|
+
let identifier;
|
|
1179
|
+
if (jwtIssuer.method == "did") {
|
|
1180
|
+
identifier = jwtIssuer.didUrl;
|
|
1181
|
+
} else if (jwtIssuer.method == "x5c") {
|
|
1182
|
+
identifier = jwtIssuer.x5c;
|
|
1183
|
+
} else {
|
|
1184
|
+
return Promise.reject(Error(`JWT issuer method ${jwtIssuer.method} not yet supported`));
|
|
1185
|
+
}
|
|
1186
|
+
const result = await context.agent.jwtCreateJwsCompactSignature({
|
|
1187
|
+
// FIXME fix cose-key inference
|
|
1188
|
+
// @ts-ignore
|
|
1189
|
+
issuer: {
|
|
1190
|
+
identifier,
|
|
1191
|
+
kmsKeyRef: idOpts.kmsKeyRef,
|
|
1192
|
+
noIdentifierInHeader: false
|
|
1193
|
+
},
|
|
1194
|
+
// FIXME fix JWK key_ops
|
|
1195
|
+
// @ts-ignore
|
|
1196
|
+
protectedHeader: jwt.header,
|
|
1197
|
+
payload: jwt.payload
|
|
1198
|
+
});
|
|
1199
|
+
return result.jwt;
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1202
|
+
__name(createJwtCallbackWithOpOpts, "createJwtCallbackWithOpOpts");
|
|
1203
|
+
function getVerifyJwtCallback(_opts, context) {
|
|
1204
|
+
return async (_jwtVerifier, jwt) => {
|
|
1205
|
+
const result = await context.agent.jwtVerifyJwsSignature({
|
|
1206
|
+
jws: jwt.raw
|
|
1207
|
+
});
|
|
1208
|
+
console.log(result.message);
|
|
1209
|
+
return !result.error;
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
__name(getVerifyJwtCallback, "getVerifyJwtCallback");
|
|
1213
|
+
async function createOP({ opOptions, idOpts: idOpts1, context }) {
|
|
1214
|
+
return (await createOPBuilder({
|
|
1215
|
+
opOptions,
|
|
1216
|
+
idOpts: idOpts1,
|
|
1217
|
+
context
|
|
1218
|
+
})).build();
|
|
1219
|
+
}
|
|
1220
|
+
__name(createOP, "createOP");
|
|
1221
|
+
function getSigningAlgo(type) {
|
|
1222
|
+
switch (type) {
|
|
1223
|
+
case "Ed25519":
|
|
1224
|
+
return SigningAlgo.EDDSA;
|
|
1225
|
+
case "Secp256k1":
|
|
1226
|
+
return SigningAlgo.ES256K;
|
|
1227
|
+
case "Secp256r1":
|
|
1228
|
+
return SigningAlgo.ES256;
|
|
1229
|
+
// @ts-ignore
|
|
1230
|
+
case "RSA":
|
|
1231
|
+
return SigningAlgo.RS256;
|
|
1232
|
+
default:
|
|
1233
|
+
throw Error("Key type not yet supported");
|
|
1619
1234
|
}
|
|
1620
|
-
|
|
1621
|
-
|
|
1235
|
+
}
|
|
1236
|
+
__name(getSigningAlgo, "getSigningAlgo");
|
|
1237
|
+
|
|
1238
|
+
// src/session/OID4VP.ts
|
|
1239
|
+
var OID4VP = class _OID4VP {
|
|
1240
|
+
static {
|
|
1241
|
+
__name(this, "OID4VP");
|
|
1622
1242
|
}
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
credential_format: "dc+sd-jwt"
|
|
1628
|
-
};
|
|
1629
|
-
} else if ("docType" in payload && "namespaces" in payload) {
|
|
1630
|
-
return {
|
|
1631
|
-
docType: payload.docType,
|
|
1632
|
-
namespaces: payload.namespaces,
|
|
1633
|
-
claims: payload
|
|
1634
|
-
};
|
|
1635
|
-
} else {
|
|
1636
|
-
return {
|
|
1637
|
-
claims: payload,
|
|
1638
|
-
credential_format: "jwt_vc_json"
|
|
1639
|
-
};
|
|
1243
|
+
//private readonly session: OpSession
|
|
1244
|
+
// private readonly allIdentifiers: string[]
|
|
1245
|
+
// private readonly hasher?: HasherSync
|
|
1246
|
+
constructor(args) {
|
|
1640
1247
|
}
|
|
1641
|
-
|
|
1642
|
-
|
|
1248
|
+
static async init(session, allIdentifiers, hasher) {
|
|
1249
|
+
return new _OID4VP({
|
|
1250
|
+
session,
|
|
1251
|
+
allIdentifiers: allIdentifiers ?? await session.getSupportedDIDs(),
|
|
1252
|
+
hasher
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1255
|
+
};
|
|
1643
1256
|
|
|
1644
|
-
// src/
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1257
|
+
// src/session/OpSession.ts
|
|
1258
|
+
import { OP as OP2, URI } from "@sphereon/did-auth-siop";
|
|
1259
|
+
import { getAgentDIDMethods, getAgentResolver } from "@sphereon/ssi-sdk-ext.did-utils";
|
|
1260
|
+
import { encodeBase64url } from "@sphereon/ssi-sdk.core";
|
|
1261
|
+
import { parseDid } from "@sphereon/ssi-types";
|
|
1262
|
+
import { v4 } from "uuid";
|
|
1263
|
+
import { Loggers as Loggers3 } from "@sphereon/ssi-types";
|
|
1264
|
+
var logger3 = Loggers3.DEFAULT.get("sphereon:oid4vp:OpSession");
|
|
1265
|
+
var OpSession = class _OpSession {
|
|
1266
|
+
static {
|
|
1267
|
+
__name(this, "OpSession");
|
|
1268
|
+
}
|
|
1269
|
+
ts = (/* @__PURE__ */ new Date()).getDate();
|
|
1270
|
+
id;
|
|
1271
|
+
options;
|
|
1272
|
+
context;
|
|
1273
|
+
requestJwtOrUri;
|
|
1274
|
+
verifiedAuthorizationRequest;
|
|
1275
|
+
_nonce;
|
|
1276
|
+
_state;
|
|
1277
|
+
constructor(options) {
|
|
1278
|
+
this.id = options.sessionId;
|
|
1279
|
+
this.options = options.op;
|
|
1280
|
+
this.context = options.context;
|
|
1281
|
+
this.requestJwtOrUri = options.requestJwtOrUri;
|
|
1282
|
+
}
|
|
1283
|
+
static async init(options) {
|
|
1284
|
+
return new _OpSession(options);
|
|
1285
|
+
}
|
|
1286
|
+
async getAuthorizationRequest() {
|
|
1287
|
+
if (!this.verifiedAuthorizationRequest) {
|
|
1288
|
+
const op = await createOP({
|
|
1289
|
+
opOptions: this.options,
|
|
1290
|
+
context: this.context
|
|
1291
|
+
});
|
|
1292
|
+
this.verifiedAuthorizationRequest = await op.verifyAuthorizationRequest(this.requestJwtOrUri);
|
|
1293
|
+
this._nonce = await this.verifiedAuthorizationRequest.authorizationRequest.getMergedProperty("nonce");
|
|
1294
|
+
this._state = await this.verifiedAuthorizationRequest.authorizationRequest.getMergedProperty("state");
|
|
1295
|
+
await this.getSupportedDIDMethods();
|
|
1655
1296
|
}
|
|
1656
|
-
|
|
1657
|
-
logger3.log(`EBSI key created: ${newIdentifier.did}`);
|
|
1658
|
-
if (created) {
|
|
1659
|
-
await agentContext.agent.emit(Siopv2HolderEvent.IDENTIFIER_CREATED, {
|
|
1660
|
-
result: newIdentifier
|
|
1661
|
-
});
|
|
1297
|
+
return this.verifiedAuthorizationRequest;
|
|
1662
1298
|
}
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
}
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
}
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
};
|
|
1678
|
-
let { idOpts: idOpts2, isFirstParty, hasher = defaultHasher2 } = args;
|
|
1679
|
-
if (connectionType !== ConnectionType.SIOPv2_OpenID4VP) {
|
|
1680
|
-
return Promise.reject(Error(`No supported authentication provider for type: ${connectionType}`));
|
|
1299
|
+
async getAuthorizationRequestURI() {
|
|
1300
|
+
return await URI.fromAuthorizationRequest((await this.getAuthorizationRequest()).authorizationRequest);
|
|
1301
|
+
}
|
|
1302
|
+
get nonce() {
|
|
1303
|
+
if (!this._nonce) {
|
|
1304
|
+
throw Error("No nonce available. Please get authorization request first");
|
|
1305
|
+
}
|
|
1306
|
+
return this._nonce;
|
|
1307
|
+
}
|
|
1308
|
+
get state() {
|
|
1309
|
+
if (!this._state) {
|
|
1310
|
+
throw Error("No state available. Please get authorization request first");
|
|
1311
|
+
}
|
|
1312
|
+
return this._state;
|
|
1681
1313
|
}
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1314
|
+
clear() {
|
|
1315
|
+
this._nonce = void 0;
|
|
1316
|
+
this._state = void 0;
|
|
1317
|
+
this.verifiedAuthorizationRequest = void 0;
|
|
1318
|
+
return this;
|
|
1319
|
+
}
|
|
1320
|
+
async getSupportedDIDMethods(didPrefix) {
|
|
1321
|
+
const agentMethods = this.getAgentDIDMethodsSupported({
|
|
1322
|
+
didPrefix
|
|
1323
|
+
});
|
|
1324
|
+
let rpMethods = await this.getRPDIDMethodsSupported({
|
|
1325
|
+
didPrefix,
|
|
1326
|
+
agentMethods
|
|
1694
1327
|
});
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
if (typeof firstUniqueDC !== "object" || !("digitalCredential" in firstUniqueDC)) {
|
|
1700
|
-
return Promise.reject(Error("SiopMachine only supports UniqueDigitalCredentials for now"));
|
|
1328
|
+
logger3.debug(`RP supports subject syntax types: ${JSON.stringify(this.getSubjectSyntaxTypesSupported())}`);
|
|
1329
|
+
if (rpMethods.dids.length === 0) {
|
|
1330
|
+
logger3.debug(`RP does not support DIDs. Supported: ${JSON.stringify(this.getSubjectSyntaxTypesSupported())}`);
|
|
1331
|
+
return [];
|
|
1701
1332
|
}
|
|
1702
|
-
let
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
`did:jwk:${encodeJoseBlob(firstVC.decodedPayload.cnf?.jwk)}#0`
|
|
1708
|
-
) : firstVC.decodedPayload.sub : Array.isArray(firstVC.credentialSubject) ? firstVC.credentialSubject[0].id : firstVC.credentialSubject.id;
|
|
1709
|
-
if (!digitalCredential.kmsKeyRef) {
|
|
1710
|
-
if (!holder) {
|
|
1711
|
-
return Promise.reject(`No holder found and no kmsKeyRef in DB. Cannot determine identifier to use`);
|
|
1712
|
-
}
|
|
1713
|
-
try {
|
|
1714
|
-
identifier = await session.context.agent.identifierManagedGet({
|
|
1715
|
-
identifier: holder
|
|
1716
|
-
});
|
|
1717
|
-
} catch (e) {
|
|
1718
|
-
logger3.debug(`Holder DID not found: ${holder}`);
|
|
1719
|
-
throw e;
|
|
1720
|
-
}
|
|
1721
|
-
} else if (isOID4VCIssuerIdentifier2(digitalCredential.kmsKeyRef)) {
|
|
1722
|
-
identifier = await session.context.agent.identifierManagedGetByOID4VCIssuer({
|
|
1723
|
-
identifier: firstUniqueDC.digitalCredential.kmsKeyRef
|
|
1724
|
-
});
|
|
1333
|
+
let intersection;
|
|
1334
|
+
if (rpMethods.dids.includes("did")) {
|
|
1335
|
+
intersection = agentMethods && agentMethods.length > 0 ? agentMethods : (await getAgentDIDMethods(this.context)).map((method) => convertDidMethod(method, didPrefix));
|
|
1336
|
+
} else if (!agentMethods || agentMethods.length === 0) {
|
|
1337
|
+
intersection = rpMethods.dids?.map((method) => convertDidMethod(method, didPrefix));
|
|
1725
1338
|
} else {
|
|
1726
|
-
|
|
1727
|
-
case "DID":
|
|
1728
|
-
identifier = await session.context.agent.identifierManagedGetByDid({
|
|
1729
|
-
identifier: digitalCredential.subjectCorrelationId ?? holder,
|
|
1730
|
-
kmsKeyRef: digitalCredential.kmsKeyRef
|
|
1731
|
-
});
|
|
1732
|
-
break;
|
|
1733
|
-
// TODO other implementations?
|
|
1734
|
-
default:
|
|
1735
|
-
if (digitalCredential.subjectCorrelationId?.startsWith("did:") || holder?.startsWith("did:")) {
|
|
1736
|
-
identifier = await session.context.agent.identifierManagedGetByDid({
|
|
1737
|
-
identifier: digitalCredential.subjectCorrelationId ?? holder,
|
|
1738
|
-
kmsKeyRef: digitalCredential.kmsKeyRef
|
|
1739
|
-
});
|
|
1740
|
-
} else {
|
|
1741
|
-
identifier = await session.context.agent.identifierManagedGetByKid({
|
|
1742
|
-
identifier: digitalCredential.subjectCorrelationId ?? holder ?? digitalCredential.kmsKeyRef,
|
|
1743
|
-
kmsKeyRef: digitalCredential.kmsKeyRef
|
|
1744
|
-
});
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1339
|
+
intersection = agentMethods.filter((value) => rpMethods.dids.includes(value));
|
|
1747
1340
|
}
|
|
1748
|
-
if (
|
|
1749
|
-
|
|
1341
|
+
if (intersection.length === 0) {
|
|
1342
|
+
throw Error("No matching DID methods between agent and relying party");
|
|
1750
1343
|
}
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1344
|
+
return intersection.map((value) => convertDidMethod(value, didPrefix));
|
|
1345
|
+
}
|
|
1346
|
+
getAgentDIDMethodsSupported(opts) {
|
|
1347
|
+
const agentMethods = this.options.supportedDIDMethods?.map((method) => convertDidMethod(method, opts.didPrefix));
|
|
1348
|
+
logger3.debug(`agent methods: ${JSON.stringify(agentMethods)}`);
|
|
1349
|
+
return agentMethods;
|
|
1350
|
+
}
|
|
1351
|
+
async getSubjectSyntaxTypesSupported() {
|
|
1352
|
+
const authReq = await this.getAuthorizationRequest();
|
|
1353
|
+
const subjectSyntaxTypesSupported = authReq.registrationMetadataPayload?.subject_syntax_types_supported;
|
|
1354
|
+
return subjectSyntaxTypesSupported ?? [];
|
|
1355
|
+
}
|
|
1356
|
+
async getRPDIDMethodsSupported(opts) {
|
|
1357
|
+
let keyType;
|
|
1358
|
+
const agentMethods = (opts.agentMethods ?? this.getAgentDIDMethodsSupported(opts))?.map((method) => convertDidMethod(method, opts.didPrefix)) ?? [];
|
|
1359
|
+
logger3.debug(`agent methods supported: ${JSON.stringify(agentMethods)}`);
|
|
1360
|
+
const authReq = await this.getAuthorizationRequest();
|
|
1361
|
+
const subjectSyntaxTypesSupported = authReq.registrationMetadataPayload?.subject_syntax_types_supported?.map((method) => convertDidMethod(method, opts.didPrefix)).filter((val) => !val.startsWith("did"));
|
|
1362
|
+
logger3.debug(`subject syntax types supported in rp method supported: ${JSON.stringify(subjectSyntaxTypesSupported)}`);
|
|
1363
|
+
const aud = await authReq.authorizationRequest.getMergedProperty("aud");
|
|
1364
|
+
let rpMethods = [];
|
|
1365
|
+
if (aud && aud.startsWith("did:")) {
|
|
1366
|
+
const didMethod = convertDidMethod(parseDid(aud).method, opts.didPrefix);
|
|
1367
|
+
logger3.debug(`aud did method: ${didMethod}`);
|
|
1368
|
+
if (subjectSyntaxTypesSupported && subjectSyntaxTypesSupported.length > 0 && !subjectSyntaxTypesSupported.includes("did") && !subjectSyntaxTypesSupported.includes(didMethod)) {
|
|
1369
|
+
throw Error(`The aud DID method ${didMethod} is not in the supported types ${subjectSyntaxTypesSupported}`);
|
|
1757
1370
|
}
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
} else if (
|
|
1762
|
-
|
|
1371
|
+
rpMethods = [
|
|
1372
|
+
didMethod
|
|
1373
|
+
];
|
|
1374
|
+
} else if (subjectSyntaxTypesSupported) {
|
|
1375
|
+
rpMethods = (Array.isArray(subjectSyntaxTypesSupported) ? subjectSyntaxTypesSupported : [
|
|
1376
|
+
subjectSyntaxTypesSupported
|
|
1377
|
+
]).map((method) => convertDidMethod(method, opts.didPrefix));
|
|
1763
1378
|
}
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
verifiablePresentations: mergedVerifiablePresentations
|
|
1772
|
-
},
|
|
1773
|
-
...presentationSubmission && {
|
|
1774
|
-
presentationSubmission
|
|
1775
|
-
},
|
|
1776
|
-
// todo: Change issuer value in case we do not use identifier. Use key.meta.jwkThumbprint then
|
|
1777
|
-
responseSignerOpts: idOpts2,
|
|
1778
|
-
isFirstParty
|
|
1779
|
-
});
|
|
1780
|
-
} else if (request.dcqlQuery) {
|
|
1781
|
-
if (args.verifiableCredentialsWithDefinition !== void 0 && args.verifiableCredentialsWithDefinition !== null) {
|
|
1782
|
-
const vcs = args.verifiableCredentialsWithDefinition.flatMap((vcd) => vcd.credentials);
|
|
1783
|
-
const domain = await request.authorizationRequest.getMergedProperty("client_id") ?? request.issuer ?? (request.versions.includes(SupportedVersion2.JWT_VC_PRESENTATION_PROFILE_v1) ? "https://self-issued.me/v2/openid-vc" : "https://self-issued.me/v2");
|
|
1784
|
-
logger3.debug(`NONCE: ${session.nonce}, domain: ${domain}`);
|
|
1785
|
-
const firstUniqueDC = vcs[0];
|
|
1786
|
-
if (typeof firstUniqueDC !== "object" || !("digitalCredential" in firstUniqueDC)) {
|
|
1787
|
-
return Promise.reject(Error("SiopMachine only supports UniqueDigitalCredentials for now"));
|
|
1379
|
+
const isEBSI = rpMethods.length === 0 && (authReq.issuer?.includes(".ebsi.eu") || authReq.authorizationRequest.getMergedProperty("client_id")?.includes(".ebsi.eu"));
|
|
1380
|
+
let codecName = void 0;
|
|
1381
|
+
if (isEBSI && (!aud || !aud.startsWith("http"))) {
|
|
1382
|
+
logger3.debug(`EBSI detected, adding did:key to supported DID methods for RP`);
|
|
1383
|
+
const didKeyMethod = convertDidMethod("did:key", opts.didPrefix);
|
|
1384
|
+
if (!agentMethods?.includes(didKeyMethod)) {
|
|
1385
|
+
throw Error(`EBSI detected, but agent did not support did:key. Please reconfigure agent`);
|
|
1788
1386
|
}
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1387
|
+
rpMethods = [
|
|
1388
|
+
didKeyMethod
|
|
1389
|
+
];
|
|
1390
|
+
keyType = "Secp256r1";
|
|
1391
|
+
codecName = "jwk_jcs-pub";
|
|
1392
|
+
}
|
|
1393
|
+
return {
|
|
1394
|
+
dids: rpMethods,
|
|
1395
|
+
codecName,
|
|
1396
|
+
keyType
|
|
1397
|
+
};
|
|
1398
|
+
}
|
|
1399
|
+
async getSupportedIdentifiers(opts) {
|
|
1400
|
+
const methods = await this.getSupportedDIDMethods(true);
|
|
1401
|
+
logger3.debug(`supported DID methods (did: prefix = true): ${JSON.stringify(methods)}`);
|
|
1402
|
+
if (methods.length === 0) {
|
|
1403
|
+
throw Error(`No DID methods are supported`);
|
|
1404
|
+
}
|
|
1405
|
+
const identifiers = await this.context.agent.didManagerFind().then((ids) => ids.filter((id) => methods.includes(id.provider)));
|
|
1406
|
+
if (identifiers.length === 0) {
|
|
1407
|
+
logger3.debug(`No identifiers available in agent supporting methods ${JSON.stringify(methods)}`);
|
|
1408
|
+
if (opts?.createInCaseNoDIDFound !== false) {
|
|
1409
|
+
const { codecName, keyType } = await this.getRPDIDMethodsSupported({
|
|
1410
|
+
didPrefix: true,
|
|
1411
|
+
agentMethods: methods
|
|
1811
1412
|
});
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
});
|
|
1819
|
-
break;
|
|
1820
|
-
// TODO other implementations?
|
|
1821
|
-
default:
|
|
1822
|
-
identifier = await session.context.agent.identifierManagedGetByKid({
|
|
1823
|
-
identifier: digitalCredential.subjectCorrelationId ?? holder ?? digitalCredential.kmsKeyRef,
|
|
1824
|
-
kmsKeyRef: digitalCredential.kmsKeyRef
|
|
1825
|
-
});
|
|
1826
|
-
}
|
|
1827
|
-
}
|
|
1828
|
-
console.log(`Identifier`, identifier);
|
|
1829
|
-
const dcqlRepresentations = [];
|
|
1830
|
-
vcs.forEach((vc) => {
|
|
1831
|
-
const rep = convertToDcqlCredentials(vc, args.hasher);
|
|
1832
|
-
if (rep) {
|
|
1833
|
-
dcqlRepresentations.push(rep);
|
|
1834
|
-
}
|
|
1835
|
-
});
|
|
1836
|
-
const queryResult = DcqlQuery.query(request.dcqlQuery, dcqlRepresentations);
|
|
1837
|
-
const presentation = {};
|
|
1838
|
-
for (const [key, value] of Object.entries(queryResult.credential_matches)) {
|
|
1839
|
-
const allMatches = Array.isArray(value) ? value : [
|
|
1840
|
-
value
|
|
1841
|
-
];
|
|
1842
|
-
allMatches.forEach((match) => {
|
|
1843
|
-
if (match.success) {
|
|
1844
|
-
const originalCredential = getOriginalVerifiableCredential(vcs[match.input_credential_index]);
|
|
1845
|
-
if (!originalCredential) {
|
|
1846
|
-
throw new Error(`Index ${match.input_credential_index} out of range in credentials array`);
|
|
1847
|
-
}
|
|
1848
|
-
presentation[key] = originalCredential["compactSdJwtVc"] !== void 0 ? originalCredential.compactSdJwtVc : originalCredential;
|
|
1413
|
+
const identifier = await this.context.agent.didManagerCreate({
|
|
1414
|
+
provider: methods[0],
|
|
1415
|
+
options: {
|
|
1416
|
+
codecName,
|
|
1417
|
+
keyType,
|
|
1418
|
+
type: keyType
|
|
1849
1419
|
}
|
|
1850
1420
|
});
|
|
1421
|
+
logger3.debug(`Created a new identifier for the SIOP interaction: ${identifier.did}`);
|
|
1422
|
+
identifiers.push(identifier);
|
|
1851
1423
|
}
|
|
1852
|
-
const response = session.sendAuthorizationResponse({
|
|
1853
|
-
responseSignerOpts: identifier,
|
|
1854
|
-
...{
|
|
1855
|
-
dcqlQuery: {
|
|
1856
|
-
dcqlPresentation: DcqlPresentation.parse(presentation)
|
|
1857
|
-
}
|
|
1858
|
-
}
|
|
1859
|
-
});
|
|
1860
|
-
logger3.debug(`Response: `, response);
|
|
1861
|
-
return response;
|
|
1862
1424
|
}
|
|
1425
|
+
logger3.debug(`supported identifiers: ${JSON.stringify(identifiers.map((id) => id.did))}`);
|
|
1426
|
+
return identifiers;
|
|
1863
1427
|
}
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
]
|
|
1872
|
-
}
|
|
1873
|
-
}
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
const { agent } = agentContext;
|
|
1881
|
-
const pex = new PEX2();
|
|
1882
|
-
const uniqueVerifiableCredentials = await agent.crsGetUniqueCredentials({
|
|
1883
|
-
filter: verifiableCredentialForRoleFilter2(CredentialRole.HOLDER)
|
|
1884
|
-
});
|
|
1885
|
-
const credentialBranding = await agent.ibGetCredentialBranding();
|
|
1886
|
-
const selectableCredentialsMap = /* @__PURE__ */ new Map();
|
|
1887
|
-
for (const inputDescriptor of presentationDefinition.input_descriptors) {
|
|
1888
|
-
const partialPD = buildPartialPD(inputDescriptor, presentationDefinition);
|
|
1889
|
-
const originalCredentials = uniqueVerifiableCredentials.map((uniqueVC) => {
|
|
1890
|
-
return CredentialMapper4.storedCredentialToOriginalFormat(uniqueVC.originalVerifiableCredential);
|
|
1891
|
-
});
|
|
1892
|
-
const selectionResults = pex.selectFrom(partialPD, originalCredentials);
|
|
1893
|
-
const selectableCredentials = [];
|
|
1894
|
-
for (const selectedCredential of selectionResults.verifiableCredential || []) {
|
|
1895
|
-
const filteredUniqueVC = uniqueVerifiableCredentials.find((uniqueVC) => {
|
|
1896
|
-
const proof = uniqueVC.uniformVerifiableCredential.proof;
|
|
1897
|
-
return Array.isArray(proof) ? proof.some((proofItem) => proofItem.jwt === selectedCredential) : proof.jwt === selectedCredential;
|
|
1428
|
+
async getSupportedDIDs() {
|
|
1429
|
+
return (await this.getSupportedIdentifiers()).map((id) => id.did);
|
|
1430
|
+
}
|
|
1431
|
+
async getRedirectUri() {
|
|
1432
|
+
return Promise.resolve(this.verifiedAuthorizationRequest.responseURI);
|
|
1433
|
+
}
|
|
1434
|
+
async getOID4VP(args) {
|
|
1435
|
+
return await OID4VP.init(this, args.allIdentifiers ?? [], args.hasher);
|
|
1436
|
+
}
|
|
1437
|
+
async createJarmResponseCallback({ responseOpts }) {
|
|
1438
|
+
const agent = this.context.agent;
|
|
1439
|
+
return /* @__PURE__ */ __name(async function jarmResponse(opts) {
|
|
1440
|
+
const { clientMetadata, requestObjectPayload, authorizationResponsePayload: authResponse } = opts;
|
|
1441
|
+
const jwk = await OP2.extractEncJwksFromClientMetadata(clientMetadata);
|
|
1442
|
+
const recipientKey = await agent.identifierExternalResolveByJwk({
|
|
1443
|
+
identifier: jwk
|
|
1898
1444
|
});
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1445
|
+
return await agent.jwtEncryptJweCompactJwt({
|
|
1446
|
+
recipientKey,
|
|
1447
|
+
protectedHeader: {},
|
|
1448
|
+
alg: requestObjectPayload.client_metadata.authorization_encrypted_response_alg ?? "ECDH-ES",
|
|
1449
|
+
enc: requestObjectPayload.client_metadata.authorization_encrypted_response_enc ?? "A256GCM",
|
|
1450
|
+
apv: encodeBase64url(opts.requestObjectPayload.nonce),
|
|
1451
|
+
apu: encodeBase64url(v4()),
|
|
1452
|
+
payload: authResponse,
|
|
1453
|
+
issuer: responseOpts.issuer,
|
|
1454
|
+
audience: responseOpts.audience
|
|
1455
|
+
}).then((result) => {
|
|
1456
|
+
return {
|
|
1457
|
+
response: result.jwt
|
|
1458
|
+
};
|
|
1459
|
+
});
|
|
1460
|
+
}, "jarmResponse");
|
|
1461
|
+
}
|
|
1462
|
+
async sendAuthorizationResponse(args) {
|
|
1463
|
+
const { responseSignerOpts, dcqlResponse, isFirstParty } = args;
|
|
1464
|
+
const resolveOpts = this.options.resolveOpts ?? {
|
|
1465
|
+
resolver: getAgentResolver(this.context, {
|
|
1466
|
+
uniresolverResolution: true,
|
|
1467
|
+
localResolution: true,
|
|
1468
|
+
resolverResolution: true
|
|
1469
|
+
})
|
|
1470
|
+
};
|
|
1471
|
+
if (!resolveOpts.subjectSyntaxTypesSupported || resolveOpts.subjectSyntaxTypesSupported.length === 0) {
|
|
1472
|
+
resolveOpts.subjectSyntaxTypesSupported = await this.getSupportedDIDMethods(true);
|
|
1473
|
+
}
|
|
1474
|
+
const request = await this.getAuthorizationRequest();
|
|
1475
|
+
const op = await createOP({
|
|
1476
|
+
opOptions: {
|
|
1477
|
+
...this.options,
|
|
1478
|
+
resolveOpts: {
|
|
1479
|
+
...this.options.resolveOpts
|
|
1480
|
+
},
|
|
1481
|
+
eventEmitter: this.options.eventEmitter,
|
|
1482
|
+
presentationSignCallback: this.options.presentationSignCallback,
|
|
1483
|
+
wellknownDIDVerifyCallback: this.options.wellknownDIDVerifyCallback,
|
|
1484
|
+
supportedVersions: request.versions
|
|
1485
|
+
},
|
|
1486
|
+
idOpts: responseSignerOpts,
|
|
1487
|
+
context: this.context
|
|
1488
|
+
});
|
|
1489
|
+
let issuer = responseSignerOpts.issuer;
|
|
1490
|
+
const responseOpts = {
|
|
1491
|
+
issuer,
|
|
1492
|
+
...isFirstParty && {
|
|
1493
|
+
isFirstParty
|
|
1494
|
+
},
|
|
1495
|
+
dcqlResponse
|
|
1496
|
+
};
|
|
1497
|
+
const authResponse = await op.createAuthorizationResponse(request, responseOpts);
|
|
1498
|
+
const response = await op.submitAuthorizationResponse(authResponse, await this.createJarmResponseCallback({
|
|
1499
|
+
responseOpts
|
|
1500
|
+
}));
|
|
1501
|
+
if (response.status >= 400) {
|
|
1502
|
+
throw Error(`Error ${response.status}: ${response.statusText || await response.text()}`);
|
|
1503
|
+
} else {
|
|
1504
|
+
return response;
|
|
1930
1505
|
}
|
|
1931
|
-
selectableCredentialsMap.set(inputDescriptor.id, selectableCredentials);
|
|
1932
1506
|
}
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
const contacts = await agent.cmGetContacts({
|
|
1938
|
-
filter: [
|
|
1939
|
-
{
|
|
1940
|
-
identities: {
|
|
1941
|
-
identifier: {
|
|
1942
|
-
correlationId
|
|
1943
|
-
}
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1946
|
-
]
|
|
1947
|
-
});
|
|
1948
|
-
if (contacts.length === 0) {
|
|
1949
|
-
return void 0;
|
|
1507
|
+
};
|
|
1508
|
+
function convertDidMethod(didMethod, didPrefix) {
|
|
1509
|
+
if (didPrefix === false) {
|
|
1510
|
+
return didMethod.startsWith("did:") ? didMethod.toLowerCase().replace("did:", "") : didMethod.toLowerCase();
|
|
1950
1511
|
}
|
|
1951
|
-
return
|
|
1952
|
-
}
|
|
1512
|
+
return didMethod.startsWith("did:") ? didMethod.toLowerCase() : `did:${didMethod.toLowerCase().replace("did:", "")}`;
|
|
1513
|
+
}
|
|
1514
|
+
__name(convertDidMethod, "convertDidMethod");
|
|
1953
1515
|
|
|
1954
1516
|
// src/agent/DidAuthSiopOpAuthenticator.ts
|
|
1955
1517
|
var logger4 = Loggers4.DEFAULT.options(LOGGER_NAMESPACE, {}).get(LOGGER_NAMESPACE);
|
|
@@ -1969,7 +1531,7 @@ var DidAuthSiopOpAuthenticator = class {
|
|
|
1969
1531
|
static {
|
|
1970
1532
|
__name(this, "DidAuthSiopOpAuthenticator");
|
|
1971
1533
|
}
|
|
1972
|
-
schema =
|
|
1534
|
+
schema = plugin_schema_default.IDidAuthSiopOpAuthenticator;
|
|
1973
1535
|
methods = {
|
|
1974
1536
|
siopGetOPSession: this.siopGetOPSession.bind(this),
|
|
1975
1537
|
siopRegisterOPSession: this.siopRegisterOPSession.bind(this),
|
|
@@ -2112,7 +1674,7 @@ var DidAuthSiopOpAuthenticator = class {
|
|
|
2112
1674
|
const url = verifiedAuthorizationRequest.responseURI ?? (args.url.includes("request_uri") ? decodeURIComponent(args.url.split("?request_uri=")[1].trim()) : verifiedAuthorizationRequest.issuer ?? verifiedAuthorizationRequest.registrationMetadataPayload?.client_id);
|
|
2113
1675
|
const uri = url.includes("://") ? new URL(url) : void 0;
|
|
2114
1676
|
const correlationId = uri?.hostname ?? await this.determineCorrelationId(uri, verifiedAuthorizationRequest, clientName, context);
|
|
2115
|
-
const clientId =
|
|
1677
|
+
const clientId = verifiedAuthorizationRequest.authorizationRequest.getMergedProperty("client_id");
|
|
2116
1678
|
return {
|
|
2117
1679
|
issuer: verifiedAuthorizationRequest.issuer,
|
|
2118
1680
|
correlationId,
|
|
@@ -2120,7 +1682,6 @@ var DidAuthSiopOpAuthenticator = class {
|
|
|
2120
1682
|
uri,
|
|
2121
1683
|
name: clientName,
|
|
2122
1684
|
clientId,
|
|
2123
|
-
presentationDefinitions: await verifiedAuthorizationRequest.authorizationRequest.containsResponseType("vp_token") || verifiedAuthorizationRequest.versions.every((version) => version <= SupportedVersion3.JWT_VC_PRESENTATION_PROFILE_v1) && verifiedAuthorizationRequest.presentationDefinitions && verifiedAuthorizationRequest.presentationDefinitions.length > 0 ? verifiedAuthorizationRequest.presentationDefinitions : void 0,
|
|
2124
1685
|
dcqlQuery: verifiedAuthorizationRequest.dcqlQuery
|
|
2125
1686
|
};
|
|
2126
1687
|
}
|
|
@@ -2197,75 +1758,14 @@ var DidAuthSiopOpAuthenticator = class {
|
|
|
2197
1758
|
if (authorizationRequestData === void 0) {
|
|
2198
1759
|
return Promise.reject(Error("Missing authorization request data in context"));
|
|
2199
1760
|
}
|
|
2200
|
-
const pex = new PEX3({
|
|
2201
|
-
hasher: this.hasher
|
|
2202
|
-
});
|
|
2203
|
-
const verifiableCredentialsWithDefinition = [];
|
|
2204
|
-
const dcqlCredentialsWithCredentials = /* @__PURE__ */ new Map();
|
|
2205
|
-
if (Array.isArray(authorizationRequestData.presentationDefinitions) && authorizationRequestData?.presentationDefinitions.length > 0) {
|
|
2206
|
-
try {
|
|
2207
|
-
authorizationRequestData.presentationDefinitions?.forEach((presentationDefinition) => {
|
|
2208
|
-
const { areRequiredCredentialsPresent, verifiableCredential: verifiableCredentials } = pex.selectFrom(presentationDefinition.definition, selectedCredentials.map((udc) => udc.originalVerifiableCredential));
|
|
2209
|
-
if (areRequiredCredentialsPresent !== Status2.ERROR && verifiableCredentials) {
|
|
2210
|
-
let uniqueDigitalCredentials = [];
|
|
2211
|
-
uniqueDigitalCredentials = verifiableCredentials.map((vc) => {
|
|
2212
|
-
const hash = typeof vc === "string" ? computeEntryHash(vc.split("~"[0])) : computeEntryHash(vc);
|
|
2213
|
-
const udc = selectedCredentials.find((udc2) => udc2.hash == hash || udc2.originalVerifiableCredential == vc);
|
|
2214
|
-
if (!udc) {
|
|
2215
|
-
throw Error(`UniqueDigitalCredential could not be found in store. Either the credential is not present in the store or the hash is not correct.`);
|
|
2216
|
-
}
|
|
2217
|
-
return udc;
|
|
2218
|
-
});
|
|
2219
|
-
verifiableCredentialsWithDefinition.push({
|
|
2220
|
-
definition: presentationDefinition,
|
|
2221
|
-
credentials: uniqueDigitalCredentials
|
|
2222
|
-
});
|
|
2223
|
-
}
|
|
2224
|
-
});
|
|
2225
|
-
} catch (e) {
|
|
2226
|
-
return Promise.reject(e);
|
|
2227
|
-
}
|
|
2228
|
-
if (verifiableCredentialsWithDefinition.length === 0) {
|
|
2229
|
-
return Promise.reject(Error("None of the selected credentials match any of the presentation definitions."));
|
|
2230
|
-
}
|
|
2231
|
-
} else if (authorizationRequestData.dcqlQuery) {
|
|
2232
|
-
if (this.hasMDocCredentials(selectedCredentials) || this.hasSdJwtCredentials(selectedCredentials)) {
|
|
2233
|
-
try {
|
|
2234
|
-
selectedCredentials.forEach((vc) => {
|
|
2235
|
-
if (this.isSdJwtCredential(vc)) {
|
|
2236
|
-
const payload = vc.originalVerifiableCredential.decodedPayload;
|
|
2237
|
-
const result = {
|
|
2238
|
-
claims: payload,
|
|
2239
|
-
vct: payload.vct,
|
|
2240
|
-
credential_format: "dc+sd-jwt"
|
|
2241
|
-
};
|
|
2242
|
-
dcqlCredentialsWithCredentials.set(result, vc);
|
|
2243
|
-
} else {
|
|
2244
|
-
throw Error(`Invalid credential format: ${vc.digitalCredential.documentFormat}`);
|
|
2245
|
-
}
|
|
2246
|
-
});
|
|
2247
|
-
} catch (e) {
|
|
2248
|
-
return Promise.reject(e);
|
|
2249
|
-
}
|
|
2250
|
-
const dcqlPresentationRecord = {};
|
|
2251
|
-
const queryResult = DcqlQuery2.query(authorizationRequestData.dcqlQuery, Array.from(dcqlCredentialsWithCredentials.keys()));
|
|
2252
|
-
for (const [key, value] of Object.entries(queryResult.credential_matches)) {
|
|
2253
|
-
if (value.success) {
|
|
2254
|
-
dcqlPresentationRecord[key] = this.retrieveEncodedCredential(dcqlCredentialsWithCredentials.get(value.output));
|
|
2255
|
-
}
|
|
2256
|
-
}
|
|
2257
|
-
}
|
|
2258
|
-
}
|
|
2259
1761
|
const response = await siopSendAuthorizationResponse(ConnectionType2.SIOPv2_OpenID4VP, {
|
|
2260
1762
|
sessionId: didAuthConfig.sessionId,
|
|
2261
1763
|
...args.idOpts && {
|
|
2262
1764
|
idOpts: args.idOpts
|
|
2263
1765
|
},
|
|
2264
|
-
...authorizationRequestData.presentationDefinitions !== void 0 && {
|
|
2265
|
-
verifiableCredentialsWithDefinition
|
|
2266
|
-
},
|
|
2267
1766
|
isFirstParty,
|
|
2268
|
-
hasher: this.hasher
|
|
1767
|
+
hasher: this.hasher,
|
|
1768
|
+
credentials: selectedCredentials
|
|
2269
1769
|
}, context);
|
|
2270
1770
|
const contentType = response.headers.get("content-type") || "";
|
|
2271
1771
|
let responseBody = null;
|
|
@@ -2279,30 +1779,12 @@ var DidAuthSiopOpAuthenticator = class {
|
|
|
2279
1779
|
queryParams: decodeUriAsJson(response?.url)
|
|
2280
1780
|
};
|
|
2281
1781
|
}
|
|
2282
|
-
hasMDocCredentials = /* @__PURE__ */ __name((credentials) => {
|
|
2283
|
-
return credentials.some(this.isMDocCredential);
|
|
2284
|
-
}, "hasMDocCredentials");
|
|
2285
|
-
isMDocCredential = /* @__PURE__ */ __name((credential) => {
|
|
2286
|
-
return credential.digitalCredential.documentFormat === CredentialDocumentFormat.MSO_MDOC && credential.digitalCredential.documentType === DocumentType.VC;
|
|
2287
|
-
}, "isMDocCredential");
|
|
2288
|
-
hasSdJwtCredentials = /* @__PURE__ */ __name((credentials) => {
|
|
2289
|
-
return credentials.some(this.isSdJwtCredential);
|
|
2290
|
-
}, "hasSdJwtCredentials");
|
|
2291
|
-
isSdJwtCredential = /* @__PURE__ */ __name((credential) => {
|
|
2292
|
-
return credential.digitalCredential.documentFormat === CredentialDocumentFormat.SD_JWT && credential.digitalCredential.documentType === DocumentType.VC;
|
|
2293
|
-
}, "isSdJwtCredential");
|
|
2294
|
-
retrieveEncodedCredential = /* @__PURE__ */ __name((credential) => {
|
|
2295
|
-
return credential.originalVerifiableCredential !== void 0 && credential.originalVerifiableCredential !== null && credential?.originalVerifiableCredential?.compactSdJwtVc !== void 0 && credential?.originalVerifiableCredential?.compactSdJwtVc !== null ? credential.originalVerifiableCredential.compactSdJwtVc : credential.originalVerifiableCredential;
|
|
2296
|
-
}, "retrieveEncodedCredential");
|
|
2297
1782
|
async siopGetSelectableCredentials(args, context) {
|
|
2298
1783
|
const { authorizationRequestData } = args;
|
|
2299
|
-
if (!authorizationRequestData
|
|
2300
|
-
return Promise.reject(Error("Missing required
|
|
1784
|
+
if (!authorizationRequestData?.dcqlQuery) {
|
|
1785
|
+
return Promise.reject(Error("Missing required dcql query in context"));
|
|
2301
1786
|
}
|
|
2302
|
-
|
|
2303
|
-
return Promise.reject(Error("Multiple presentation definitions present"));
|
|
2304
|
-
}
|
|
2305
|
-
return getSelectableCredentials(authorizationRequestData.presentationDefinitions[0].definition, context);
|
|
1787
|
+
return getSelectableCredentials(authorizationRequestData?.dcqlQuery, context);
|
|
2306
1788
|
}
|
|
2307
1789
|
};
|
|
2308
1790
|
|
|
@@ -2388,9 +1870,6 @@ var Siopv2OID4VPLinkHandler = class extends LinkHandlerAdapter {
|
|
|
2388
1870
|
}
|
|
2389
1871
|
}
|
|
2390
1872
|
};
|
|
2391
|
-
|
|
2392
|
-
// src/index.ts
|
|
2393
|
-
var schema = require_plugin_schema();
|
|
2394
1873
|
export {
|
|
2395
1874
|
DEFAULT_JWT_PROOF_TYPE,
|
|
2396
1875
|
DID_PREFIX,
|
|
@@ -2408,14 +1887,14 @@ export {
|
|
|
2408
1887
|
Siopv2MachineStates,
|
|
2409
1888
|
Siopv2OID4VPLinkHandler,
|
|
2410
1889
|
SupportedLanguage,
|
|
1890
|
+
convertToDcqlCredentials,
|
|
2411
1891
|
createJwtCallbackWithIdOpts,
|
|
2412
1892
|
createJwtCallbackWithOpOpts,
|
|
2413
1893
|
createOID4VPPresentationSignCallback,
|
|
2414
1894
|
createOP,
|
|
2415
1895
|
createOPBuilder,
|
|
2416
1896
|
didAuthSiopOpAuthenticatorMethods,
|
|
2417
|
-
events,
|
|
2418
1897
|
getSigningAlgo,
|
|
2419
|
-
schema
|
|
1898
|
+
plugin_schema_default as schema
|
|
2420
1899
|
};
|
|
2421
1900
|
//# sourceMappingURL=index.js.map
|