@sphereon/oid4vci-client 0.21.0 → 0.21.1-next.2

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.d.cts CHANGED
@@ -366,9 +366,25 @@ declare const generateMissingPKCEOpts: (pkce: PKCEOpts) => PKCEOpts;
366
366
 
367
367
  declare function sendNotification(credentialRequestOpts: Partial<CredentialRequestOpts>, request: NotificationRequest, accessToken?: string): Promise<NotificationResponseResult>;
368
368
 
369
+ /**
370
+ * Determines the well-known location(s) to try for a host and endpoint type, in order of preference.
371
+ *
372
+ * OID4VCI 1.0 final and RFC 8414 require the well-known path to be inserted between the host and the path component
373
+ * (https://host/.well-known/openid-credential-issuer/tenant), whereas earlier OID4VCI drafts appended it to the full
374
+ * URL (https://host/tenant/.well-known/openid-credential-issuer). For the credential issuer and OAuth AS metadata we
375
+ * default to the current spec behavior with the legacy location as fallback. For openid-configuration the appended
376
+ * form is the primary location per OIDC Discovery, with the RFC 8414 form as fallback.
377
+ *
378
+ * @param host The host, including an optional path component
379
+ * @param endpointType The endpoint type, currently supports OID4VCI, OIDC and OAuth2 endpoint types
380
+ */
381
+ declare const determineWellknownLocations: (host: string, endpointType: WellKnownEndpoints) => string[];
369
382
  /**
370
383
  * Allows to retrieve information from a well-known location
371
384
  *
385
+ * Tries all applicable locations for the endpoint type (see determineWellknownLocations) and returns the first
386
+ * successful response containing a JSON object body.
387
+ *
372
388
  * @param host The host
373
389
  * @param endpointType The endpoint type, currently supports OID4VCI, OIDC and OAuth2 endpoint types
374
390
  * @param opts Options, like for instance whether an error should be thrown in case the endpoint doesn't exist
@@ -701,4 +717,4 @@ declare class OpenID4VCIClient {
701
717
 
702
718
  declare const LOG: ISimpleLogger<string>;
703
719
 
704
- export { AccessTokenClient, type CreateCredentialRequestOpts, CredentialOfferClient, CredentialOfferClientV1_0_15, CredentialRequestClient, CredentialRequestClientBuilder, CredentialRequestClientBuilderV1_0, CredentialRequestClientBuilderV1_0_15, type CredentialRequestOpts, type EndpointMetadataResult, LOG, MetadataClient, MetadataClientV1_0, MetadataClientV1_0_15, OpenID4VCIClient, type OpenID4VCIClientState, type OpenID4VCIClientStateV1_0_15, OpenID4VCIClientV1_0_15, ProofOfPossessionBuilder, acquireAuthorizationChallengeAuthCode, acquireAuthorizationChallengeAuthCodeUsingRequest, buildProof, constructBaseResponse, createAuthorizationChallengeRequest, createAuthorizationRequestUrl, createJwtBearerClientAssertion, createSignedAuthRequestWhenNeeded, generateMissingPKCEOpts, handleCredentialOfferUri, isUriEncoded, retrieveWellknown, sendAuthorizationChallengeRequest, sendNotification };
720
+ export { AccessTokenClient, type CreateCredentialRequestOpts, CredentialOfferClient, CredentialOfferClientV1_0_15, CredentialRequestClient, CredentialRequestClientBuilder, CredentialRequestClientBuilderV1_0, CredentialRequestClientBuilderV1_0_15, type CredentialRequestOpts, type EndpointMetadataResult, LOG, MetadataClient, MetadataClientV1_0, MetadataClientV1_0_15, OpenID4VCIClient, type OpenID4VCIClientState, type OpenID4VCIClientStateV1_0_15, OpenID4VCIClientV1_0_15, ProofOfPossessionBuilder, acquireAuthorizationChallengeAuthCode, acquireAuthorizationChallengeAuthCodeUsingRequest, buildProof, constructBaseResponse, createAuthorizationChallengeRequest, createAuthorizationRequestUrl, createJwtBearerClientAssertion, createSignedAuthRequestWhenNeeded, determineWellknownLocations, generateMissingPKCEOpts, handleCredentialOfferUri, isUriEncoded, retrieveWellknown, sendAuthorizationChallengeRequest, sendNotification };
package/dist/index.d.ts CHANGED
@@ -366,9 +366,25 @@ declare const generateMissingPKCEOpts: (pkce: PKCEOpts) => PKCEOpts;
366
366
 
367
367
  declare function sendNotification(credentialRequestOpts: Partial<CredentialRequestOpts>, request: NotificationRequest, accessToken?: string): Promise<NotificationResponseResult>;
368
368
 
369
+ /**
370
+ * Determines the well-known location(s) to try for a host and endpoint type, in order of preference.
371
+ *
372
+ * OID4VCI 1.0 final and RFC 8414 require the well-known path to be inserted between the host and the path component
373
+ * (https://host/.well-known/openid-credential-issuer/tenant), whereas earlier OID4VCI drafts appended it to the full
374
+ * URL (https://host/tenant/.well-known/openid-credential-issuer). For the credential issuer and OAuth AS metadata we
375
+ * default to the current spec behavior with the legacy location as fallback. For openid-configuration the appended
376
+ * form is the primary location per OIDC Discovery, with the RFC 8414 form as fallback.
377
+ *
378
+ * @param host The host, including an optional path component
379
+ * @param endpointType The endpoint type, currently supports OID4VCI, OIDC and OAuth2 endpoint types
380
+ */
381
+ declare const determineWellknownLocations: (host: string, endpointType: WellKnownEndpoints) => string[];
369
382
  /**
370
383
  * Allows to retrieve information from a well-known location
371
384
  *
385
+ * Tries all applicable locations for the endpoint type (see determineWellknownLocations) and returns the first
386
+ * successful response containing a JSON object body.
387
+ *
372
388
  * @param host The host
373
389
  * @param endpointType The endpoint type, currently supports OID4VCI, OIDC and OAuth2 endpoint types
374
390
  * @param opts Options, like for instance whether an error should be thrown in case the endpoint doesn't exist
@@ -701,4 +717,4 @@ declare class OpenID4VCIClient {
701
717
 
702
718
  declare const LOG: ISimpleLogger<string>;
703
719
 
704
- export { AccessTokenClient, type CreateCredentialRequestOpts, CredentialOfferClient, CredentialOfferClientV1_0_15, CredentialRequestClient, CredentialRequestClientBuilder, CredentialRequestClientBuilderV1_0, CredentialRequestClientBuilderV1_0_15, type CredentialRequestOpts, type EndpointMetadataResult, LOG, MetadataClient, MetadataClientV1_0, MetadataClientV1_0_15, OpenID4VCIClient, type OpenID4VCIClientState, type OpenID4VCIClientStateV1_0_15, OpenID4VCIClientV1_0_15, ProofOfPossessionBuilder, acquireAuthorizationChallengeAuthCode, acquireAuthorizationChallengeAuthCodeUsingRequest, buildProof, constructBaseResponse, createAuthorizationChallengeRequest, createAuthorizationRequestUrl, createJwtBearerClientAssertion, createSignedAuthRequestWhenNeeded, generateMissingPKCEOpts, handleCredentialOfferUri, isUriEncoded, retrieveWellknown, sendAuthorizationChallengeRequest, sendNotification };
720
+ export { AccessTokenClient, type CreateCredentialRequestOpts, CredentialOfferClient, CredentialOfferClientV1_0_15, CredentialRequestClient, CredentialRequestClientBuilder, CredentialRequestClientBuilderV1_0, CredentialRequestClientBuilderV1_0_15, type CredentialRequestOpts, type EndpointMetadataResult, LOG, MetadataClient, MetadataClientV1_0, MetadataClientV1_0_15, OpenID4VCIClient, type OpenID4VCIClientState, type OpenID4VCIClientStateV1_0_15, OpenID4VCIClientV1_0_15, ProofOfPossessionBuilder, acquireAuthorizationChallengeAuthCode, acquireAuthorizationChallengeAuthCodeUsingRequest, buildProof, constructBaseResponse, createAuthorizationChallengeRequest, createAuthorizationRequestUrl, createJwtBearerClientAssertion, createSignedAuthRequestWhenNeeded, determineWellknownLocations, generateMissingPKCEOpts, handleCredentialOfferUri, isUriEncoded, retrieveWellknown, sendAuthorizationChallengeRequest, sendNotification };
package/dist/index.js CHANGED
@@ -68,17 +68,70 @@ async function sendNotification(credentialRequestOpts, request, accessToken) {
68
68
  __name(sendNotification, "sendNotification");
69
69
 
70
70
  // lib/functions/OpenIDUtils.ts
71
- import { getJson } from "@sphereon/oid4vci-common";
71
+ import { getJson, WellKnownEndpoints } from "@sphereon/oid4vci-common";
72
72
  import { Loggers } from "@sphereon/ssi-types";
73
73
  var logger = Loggers.DEFAULT.get("sphereon:openid4vci:openid-utils");
74
+ var determineWellknownLocations = /* @__PURE__ */ __name((host, endpointType) => {
75
+ const base = host.endsWith("/") ? host.slice(0, -1) : host;
76
+ const legacyLocation = `${base}${endpointType}`;
77
+ try {
78
+ const url = new URL(base);
79
+ let pathname = url.pathname;
80
+ while (pathname.endsWith("/")) {
81
+ pathname = pathname.slice(0, -1);
82
+ }
83
+ if (pathname.length > 0) {
84
+ const rfc8414Location = `${url.origin}${endpointType}${pathname}`;
85
+ return endpointType === WellKnownEndpoints.OPENID_CONFIGURATION ? [
86
+ legacyLocation,
87
+ rfc8414Location
88
+ ] : [
89
+ rfc8414Location,
90
+ legacyLocation
91
+ ];
92
+ }
93
+ } catch (error) {
94
+ logger.debug(`host ${host} could not be parsed as URL, using legacy well-known location only`);
95
+ }
96
+ return [
97
+ legacyLocation
98
+ ];
99
+ }, "determineWellknownLocations");
74
100
  var retrieveWellknown = /* @__PURE__ */ __name(async (host, endpointType, opts) => {
75
- const result = await getJson(`${host.endsWith("/") ? host.slice(0, -1) : host}${endpointType}`, {
76
- exceptionOnHttpErrorStatus: opts?.errorOnNotFound
77
- });
78
- if (result.origResponse.status >= 400) {
79
- logger.debug(`host ${host} with endpoint type ${endpointType} status: ${result.origResponse.status}, ${result.origResponse.statusText}`);
101
+ const locations = determineWellknownLocations(host, endpointType);
102
+ let successResult;
103
+ let errorResult;
104
+ let lastError;
105
+ for (const location of locations) {
106
+ try {
107
+ const response = await getJson(location, {
108
+ exceptionOnHttpErrorStatus: false
109
+ });
110
+ if (response.origResponse.status < 400) {
111
+ if (response.successBody !== void 0 && typeof response.successBody === "object" && response.successBody !== null) {
112
+ return response;
113
+ }
114
+ successResult = successResult ?? response;
115
+ } else {
116
+ logger.debug(`host ${host} with endpoint type ${endpointType} at ${location} status: ${response.origResponse.status}, ${response.origResponse.statusText}`);
117
+ errorResult = errorResult ?? response;
118
+ }
119
+ } catch (error) {
120
+ logger.debug(`host ${host} with endpoint type ${endpointType} at ${location} error: ${error instanceof Error ? error.message : error}`);
121
+ lastError = error;
122
+ }
80
123
  }
81
- return result;
124
+ if (successResult) {
125
+ return successResult;
126
+ }
127
+ if (errorResult) {
128
+ if (opts?.errorOnNotFound) {
129
+ const error = JSON.stringify(errorResult.errorBody ?? {});
130
+ throw new Error(error === "{}" ? '{"error": "not found"}' : error);
131
+ }
132
+ return errorResult;
133
+ }
134
+ throw lastError instanceof Error ? lastError : new Error(`Could not retrieve well-known ${endpointType} for host ${host}`);
82
135
  }, "retrieveWellknown");
83
136
 
84
137
  // lib/functions/AccessTokenUtil.ts
@@ -411,7 +464,7 @@ function shouldRetryResourceRequestWithDPoPNonce(response) {
411
464
  __name(shouldRetryResourceRequestWithDPoPNonce, "shouldRetryResourceRequestWithDPoPNonce");
412
465
 
413
466
  // lib/MetadataClientV1_0_15.ts
414
- import { getIssuerFromCredentialOfferPayload, processSignedMetadata, WellKnownEndpoints } from "@sphereon/oid4vci-common";
467
+ import { getIssuerFromCredentialOfferPayload, processSignedMetadata, WellKnownEndpoints as WellKnownEndpoints2 } from "@sphereon/oid4vci-common";
415
468
  import { Loggers as Loggers2 } from "@sphereon/ssi-types";
416
469
  var logger2 = Loggers2.DEFAULT.get("sphereon:oid4vci:metadata");
417
470
  var MetadataClientV1_0_15 = class _MetadataClientV1_0_15 {
@@ -473,7 +526,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
473
526
  authorization_servers = credentialIssuerMetadata.authorization_servers;
474
527
  }
475
528
  }
476
- let response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints.OPENID_CONFIGURATION, {
529
+ let response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints2.OPENID_CONFIGURATION, {
477
530
  errorOnNotFound: false
478
531
  });
479
532
  let authMetadata = response.successBody;
@@ -481,7 +534,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
481
534
  logger2.debug(`Issuer ${issuer} has OpenID Connect Server metadata in well-known location`);
482
535
  authorizationServerType = "OIDC";
483
536
  } else {
484
- response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints.OAUTH_AS, {
537
+ response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints2.OAUTH_AS, {
485
538
  errorOnNotFound: false
486
539
  });
487
540
  authMetadata = response.successBody;
@@ -597,7 +650,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
597
650
  * @param opts
598
651
  */
599
652
  static async retrieveOpenID4VCIServerMetadata(issuerHost, opts) {
600
- return retrieveWellknown(issuerHost, WellKnownEndpoints.OPENID4VCI_ISSUER, {
653
+ return retrieveWellknown(issuerHost, WellKnownEndpoints2.OPENID4VCI_ISSUER, {
601
654
  errorOnNotFound: opts?.errorOnNotFound === void 0 ? true : opts.errorOnNotFound
602
655
  });
603
656
  }
@@ -846,7 +899,7 @@ import { CodeChallengeMethod as CodeChallengeMethod2, convertJsonToURI as conver
846
899
  import { Loggers as Loggers4 } from "@sphereon/ssi-types";
847
900
 
848
901
  // lib/MetadataClient.ts
849
- import { determineSpecVersionFromOffer, determineVersionsFromIssuerMetadata, getIssuerFromCredentialOfferPayload as getIssuerFromCredentialOfferPayload3, OpenId4VCIVersion as OpenId4VCIVersion2, processSignedMetadata as processSignedMetadata2, WellKnownEndpoints as WellKnownEndpoints2 } from "@sphereon/oid4vci-common";
902
+ import { determineSpecVersionFromOffer, determineVersionsFromIssuerMetadata, getIssuerFromCredentialOfferPayload as getIssuerFromCredentialOfferPayload3, OpenId4VCIVersion as OpenId4VCIVersion2, processSignedMetadata as processSignedMetadata2, WellKnownEndpoints as WellKnownEndpoints3 } from "@sphereon/oid4vci-common";
850
903
  import { Loggers as Loggers3 } from "@sphereon/ssi-types";
851
904
  var logger3 = Loggers3.DEFAULT.get("sphereon:oid4vci:metadata");
852
905
  var MetadataClient = class _MetadataClient {
@@ -920,7 +973,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
920
973
  } else {
921
974
  throw new Error(`Issuer ${issuer} does not expose /.well-known/openid-credential-issuer`);
922
975
  }
923
- let response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints2.OPENID_CONFIGURATION, {
976
+ let response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints3.OPENID_CONFIGURATION, {
924
977
  errorOnNotFound: false
925
978
  });
926
979
  let authMetadata = response.successBody;
@@ -928,7 +981,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
928
981
  logger3.debug(`Issuer ${issuer} has OpenID Connect Server metadata in well-known location`);
929
982
  authorizationServerType = "OIDC";
930
983
  } else {
931
- response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints2.OAUTH_AS, {
984
+ response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints3.OAUTH_AS, {
932
985
  errorOnNotFound: false
933
986
  });
934
987
  authMetadata = response.successBody;
@@ -1029,7 +1082,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
1029
1082
  * @param opts
1030
1083
  */
1031
1084
  static async retrieveOpenID4VCIServerMetadata(issuerHost, opts) {
1032
- return retrieveWellknown(issuerHost, WellKnownEndpoints2.OPENID4VCI_ISSUER, {
1085
+ return retrieveWellknown(issuerHost, WellKnownEndpoints3.OPENID4VCI_ISSUER, {
1033
1086
  errorOnNotFound: opts?.errorOnNotFound === void 0 ? true : opts.errorOnNotFound
1034
1087
  });
1035
1088
  }
@@ -2273,7 +2326,7 @@ var CredentialRequestClientBuilder = class _CredentialRequestClientBuilder {
2273
2326
  };
2274
2327
 
2275
2328
  // lib/MetadataClientV1_0.ts
2276
- import { getIssuerFromCredentialOfferPayload as getIssuerFromCredentialOfferPayload6, processSignedMetadata as processSignedMetadata3, WellKnownEndpoints as WellKnownEndpoints3 } from "@sphereon/oid4vci-common";
2329
+ import { getIssuerFromCredentialOfferPayload as getIssuerFromCredentialOfferPayload6, processSignedMetadata as processSignedMetadata3, WellKnownEndpoints as WellKnownEndpoints4 } from "@sphereon/oid4vci-common";
2277
2330
  import { Loggers as Loggers7 } from "@sphereon/ssi-types";
2278
2331
  var logger7 = Loggers7.DEFAULT.get("sphereon:oid4vci:metadata");
2279
2332
  var MetadataClientV1_0 = class _MetadataClientV1_0 {
@@ -2321,7 +2374,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
2321
2374
  authorization_servers = credentialIssuerMetadata.authorization_servers;
2322
2375
  }
2323
2376
  }
2324
- let response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints3.OPENID_CONFIGURATION, {
2377
+ let response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints4.OPENID_CONFIGURATION, {
2325
2378
  errorOnNotFound: false
2326
2379
  });
2327
2380
  let authMetadata = response.successBody;
@@ -2329,7 +2382,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
2329
2382
  logger7.debug(`Issuer ${issuer} has OpenID Connect Server metadata in well-known location`);
2330
2383
  authorizationServerType = "OIDC";
2331
2384
  } else {
2332
- response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints3.OAUTH_AS, {
2385
+ response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints4.OAUTH_AS, {
2333
2386
  errorOnNotFound: false
2334
2387
  });
2335
2388
  authMetadata = response.successBody;
@@ -2445,7 +2498,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
2445
2498
  };
2446
2499
  }
2447
2500
  static async retrieveOpenID4VCIServerMetadata(issuerHost, opts) {
2448
- return retrieveWellknown(issuerHost, WellKnownEndpoints3.OPENID4VCI_ISSUER, {
2501
+ return retrieveWellknown(issuerHost, WellKnownEndpoints4.OPENID4VCI_ISSUER, {
2449
2502
  errorOnNotFound: opts?.errorOnNotFound === void 0 ? true : opts.errorOnNotFound
2450
2503
  });
2451
2504
  }
@@ -3658,6 +3711,7 @@ export {
3658
3711
  createAuthorizationRequestUrl,
3659
3712
  createJwtBearerClientAssertion,
3660
3713
  createSignedAuthRequestWhenNeeded,
3714
+ determineWellknownLocations,
3661
3715
  generateMissingPKCEOpts,
3662
3716
  handleCredentialOfferUri,
3663
3717
  isUriEncoded,