@digitalbazaar/oid4-client 5.8.0 → 5.9.0
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/lib/convert/index.js +9 -2
- package/lib/oid4vp/authorizationRequest.js +30 -9
- package/lib/util.js +9 -1
- package/package.json +1 -1
package/lib/convert/index.js
CHANGED
|
@@ -139,8 +139,10 @@ export function toVpr({authorizationRequest, strict = false} = {}) {
|
|
|
139
139
|
client_id,
|
|
140
140
|
client_metadata,
|
|
141
141
|
dcql_query,
|
|
142
|
+
expected_origins,
|
|
142
143
|
nonce,
|
|
143
144
|
presentation_definition,
|
|
145
|
+
response_mode,
|
|
144
146
|
response_uri
|
|
145
147
|
} = authorizationRequest;
|
|
146
148
|
|
|
@@ -186,9 +188,14 @@ export function toVpr({authorizationRequest, strict = false} = {}) {
|
|
|
186
188
|
verifiablePresentationRequest.query = [didAuthnQuery];
|
|
187
189
|
}
|
|
188
190
|
|
|
189
|
-
// map `
|
|
191
|
+
// map `expected_origins` or `response_uri` to `domain`
|
|
190
192
|
if(response_uri !== undefined || client_id !== undefined) {
|
|
191
|
-
|
|
193
|
+
if(response_mode?.startsWith('dc_api') && !response_uri &&
|
|
194
|
+
expected_origins?.length > 0) {
|
|
195
|
+
verifiablePresentationRequest.domain = expected_origins[0];
|
|
196
|
+
} else {
|
|
197
|
+
verifiablePresentationRequest.domain = response_uri;
|
|
198
|
+
}
|
|
192
199
|
}
|
|
193
200
|
|
|
194
201
|
// map `nonce` to `challenge`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Copyright (c) 2023-
|
|
2
|
+
* Copyright (c) 2023-2026 Digital Bazaar, Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
import {
|
|
5
5
|
assert, assertOptional, base64Encode,
|
|
@@ -23,13 +23,15 @@ const SUPPORTED_CLIENT_ID_SCHEMES = new Set([
|
|
|
23
23
|
|
|
24
24
|
// get an authorization request from a verifier
|
|
25
25
|
export async function get({
|
|
26
|
-
url, getTrustedCertificates, getVerificationKey, agent
|
|
26
|
+
url, getTrustedCertificates, getVerificationKey, getPostBody, agent,
|
|
27
|
+
overrideMethod
|
|
27
28
|
} = {}) {
|
|
28
29
|
try {
|
|
29
30
|
assert(url, 'url', 'string');
|
|
30
31
|
|
|
31
32
|
let authorizationRequest;
|
|
32
33
|
let requestUrl;
|
|
34
|
+
let requestUrlMethod = 'get';
|
|
33
35
|
let expectedClientId;
|
|
34
36
|
if(url.startsWith('https://')) {
|
|
35
37
|
// the request must be retrieved via HTTP
|
|
@@ -40,6 +42,10 @@ export async function get({
|
|
|
40
42
|
expectedClientId = authorizationRequest.client_id;
|
|
41
43
|
if(authorizationRequest.request_uri) {
|
|
42
44
|
requestUrl = authorizationRequest.request_uri;
|
|
45
|
+
if(authorizationRequest.request_uri_method === 'post' ||
|
|
46
|
+
authorizationRequest.request_uri_method === 'get') {
|
|
47
|
+
requestUrlMethod = authorizationRequest.request_uri_method;
|
|
48
|
+
}
|
|
43
49
|
}
|
|
44
50
|
// if whole request is passed by reference, then it MUST be a signed JWT
|
|
45
51
|
if(authorizationRequest.request) {
|
|
@@ -52,6 +58,11 @@ export async function get({
|
|
|
52
58
|
}
|
|
53
59
|
}
|
|
54
60
|
|
|
61
|
+
// allow method override
|
|
62
|
+
if(overrideMethod) {
|
|
63
|
+
requestUrlMethod = overrideMethod;
|
|
64
|
+
}
|
|
65
|
+
|
|
55
66
|
// fetch request if necessary...
|
|
56
67
|
let fetched = false;
|
|
57
68
|
let response;
|
|
@@ -60,8 +71,9 @@ export async function get({
|
|
|
60
71
|
fetched = true;
|
|
61
72
|
({
|
|
62
73
|
payload: authorizationRequest, response, jwt
|
|
63
|
-
} = await
|
|
64
|
-
|
|
74
|
+
} = await _fetchAuthzRequest({
|
|
75
|
+
method: requestUrlMethod, requestUrl, getPostBody,
|
|
76
|
+
getTrustedCertificates, getVerificationKey, agent
|
|
65
77
|
}));
|
|
66
78
|
}
|
|
67
79
|
|
|
@@ -268,8 +280,8 @@ async function _checkClientIdSchemeRequirements({
|
|
|
268
280
|
}
|
|
269
281
|
|
|
270
282
|
let {client_id: clientId} = authorizationRequest;
|
|
271
|
-
clientId = clientId
|
|
272
|
-
clientId.slice(clientIdScheme.length +
|
|
283
|
+
clientId = clientId?.startsWith(`${clientIdScheme}:`) ?
|
|
284
|
+
clientId.slice(clientIdScheme.length + 1) : clientId;
|
|
273
285
|
|
|
274
286
|
if(clientIdScheme === 'x509_san_dns') {
|
|
275
287
|
// `x509_san_dns` requires leaf cert to have a dNSName ("domain" type) in
|
|
@@ -324,14 +336,21 @@ async function _checkClientIdSchemeRequirements({
|
|
|
324
336
|
}
|
|
325
337
|
}
|
|
326
338
|
|
|
327
|
-
async function
|
|
328
|
-
|
|
339
|
+
async function _fetchAuthzRequest({
|
|
340
|
+
method = 'get', requestUrl, getPostBody,
|
|
341
|
+
getTrustedCertificates, getVerificationKey, agent
|
|
329
342
|
}) {
|
|
330
343
|
// FIXME: every `fetchJSON` call needs to use a block list or other
|
|
331
344
|
// protections to prevent a confused deputy attack where the `requestUrl`
|
|
332
345
|
// accesses a location it should not, e.g., a URL `localhost` is used when
|
|
333
346
|
// it shouldn't be
|
|
334
|
-
const
|
|
347
|
+
const options = {url: requestUrl, agent};
|
|
348
|
+
if(method === 'post') {
|
|
349
|
+
const {body} = await getPostBody?.() ?? new URLSearchParams();
|
|
350
|
+
options.method = 'post';
|
|
351
|
+
options.body = body ?? new URLSearchParams();
|
|
352
|
+
}
|
|
353
|
+
const response = await fetchJSON(options);
|
|
335
354
|
|
|
336
355
|
// parse payload from response data...
|
|
337
356
|
const contentType = response.headers.get('content-type');
|
|
@@ -422,6 +441,7 @@ function _parseOID4VPUrl({url}) {
|
|
|
422
441
|
const {searchParams} = new URL(url);
|
|
423
442
|
const request = _get(searchParams, 'request');
|
|
424
443
|
const request_uri = _get(searchParams, 'request_uri');
|
|
444
|
+
const request_uri_method = _get(searchParams, 'request_uri_method');
|
|
425
445
|
const response_type = _get(searchParams, 'response_type');
|
|
426
446
|
const response_mode = _get(searchParams, 'response_mode');
|
|
427
447
|
const presentation_definition = _get(
|
|
@@ -452,6 +472,7 @@ function _parseOID4VPUrl({url}) {
|
|
|
452
472
|
const authorizationRequest = {
|
|
453
473
|
request,
|
|
454
474
|
request_uri,
|
|
475
|
+
request_uri_method,
|
|
455
476
|
response_type,
|
|
456
477
|
response_mode,
|
|
457
478
|
presentation_definition: presentation_definition &&
|
package/lib/util.js
CHANGED
|
@@ -47,7 +47,7 @@ export function createNamedError({message, name, details, cause} = {}) {
|
|
|
47
47
|
return error;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
export function fetchJSON({url, agent} = {}) {
|
|
50
|
+
export function fetchJSON({method = 'get', url, body, json, agent} = {}) {
|
|
51
51
|
// allow these params to be passed / configured
|
|
52
52
|
const fetchOptions = {
|
|
53
53
|
// max size for issuer config related responses (in bytes, ~4 KiB)
|
|
@@ -57,6 +57,14 @@ export function fetchJSON({url, agent} = {}) {
|
|
|
57
57
|
agent
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
+
if(method === 'post') {
|
|
61
|
+
if(body !== undefined) {
|
|
62
|
+
fetchOptions.body = body;
|
|
63
|
+
} else if(json !== undefined) {
|
|
64
|
+
fetchOptions.json = json;
|
|
65
|
+
}
|
|
66
|
+
return httpClient.post(url, fetchOptions);
|
|
67
|
+
}
|
|
60
68
|
return httpClient.get(url, fetchOptions);
|
|
61
69
|
}
|
|
62
70
|
|