@digitalbazaar/oid4-client 5.8.0 → 5.9.1

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.
@@ -62,11 +62,18 @@ export function fromVpr({
62
62
  if(verifiablePresentationRequest.domain) {
63
63
  // since a `domain` was provided, set these defaults:
64
64
  authorizationRequest.client_id = verifiablePresentationRequest.domain;
65
- authorizationRequest.response_uri = authorizationRequest.client_id;
65
+ const usesRedirectUriPrefix =
66
+ authorizationRequest.client_id?.startsWith('redirect_uri:');
67
+ authorizationRequest.response_uri = usesRedirectUriPrefix ?
68
+ authorizationRequest.client_id.slice('redirect_uri:'.length) :
69
+ authorizationRequest.client_id;
66
70
  if(useClientIdPrefix) {
67
- authorizationRequest.client_id =
68
- `redirect_uri:${authorizationRequest.client_id}`;
69
- } else {
71
+ if(!usesRedirectUriPrefix) {
72
+ authorizationRequest.client_id =
73
+ `redirect_uri:${authorizationRequest.client_id}`;
74
+ }
75
+ }
76
+ if(usesRedirectUriPrefix) {
70
77
  authorizationRequest.client_id_scheme = 'redirect_uri';
71
78
  }
72
79
  }
@@ -137,10 +144,13 @@ export function toVpr({authorizationRequest, strict = false} = {}) {
137
144
 
138
145
  const {
139
146
  client_id,
147
+ client_id_scheme,
140
148
  client_metadata,
141
149
  dcql_query,
150
+ expected_origins,
142
151
  nonce,
143
152
  presentation_definition,
153
+ response_mode,
144
154
  response_uri
145
155
  } = authorizationRequest;
146
156
 
@@ -186,9 +196,17 @@ export function toVpr({authorizationRequest, strict = false} = {}) {
186
196
  verifiablePresentationRequest.query = [didAuthnQuery];
187
197
  }
188
198
 
189
- // map `response_uri` or `client_id` to `domain`
199
+ // map `expected_origins` / `client_id` / `response_uri` to `domain`
190
200
  if(response_uri !== undefined || client_id !== undefined) {
191
- verifiablePresentationRequest.domain = response_uri ?? client_id;
201
+ if(response_mode?.startsWith('dc_api') && !response_uri &&
202
+ expected_origins?.length > 0) {
203
+ verifiablePresentationRequest.domain = expected_origins[0];
204
+ } else if(client_id_scheme === 'redirect_uri' ||
205
+ client_id?.startsWith('redirect_uri:')) {
206
+ verifiablePresentationRequest.domain = client_id ?? response_uri;
207
+ } else {
208
+ verifiablePresentationRequest.domain = response_uri;
209
+ }
192
210
  }
193
211
 
194
212
  // map `nonce` to `challenge`
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Copyright (c) 2023-2025 Digital Bazaar, Inc. All rights reserved.
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 _fetch({
64
- requestUrl, getTrustedCertificates, getVerificationKey, agent
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.startsWith(`${clientIdScheme}:`) ?
272
- clientId.slice(clientIdScheme.length + 2) : clientId;
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 _fetch({
328
- requestUrl, getTrustedCertificates, getVerificationKey, agent
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 response = await fetchJSON({url: requestUrl, agent});
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitalbazaar/oid4-client",
3
- "version": "5.8.0",
3
+ "version": "5.9.1",
4
4
  "description": "An OID4 (VC + VP) client",
5
5
  "homepage": "https://github.com/digitalbazaar/oid4-client",
6
6
  "author": {