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

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
  }
@@ -717,6 +770,9 @@ var AccessTokenClient = class _AccessTokenClient {
717
770
  }
718
771
  request.grant_type = GrantTypes.PRE_AUTHORIZED_CODE;
719
772
  request[PRE_AUTH_CODE_LITERAL2] = credentialOfferRequest?.credential_offer.grants?.[PRE_AUTH_GRANT_LITERAL2]?.[PRE_AUTH_CODE_LITERAL2];
773
+ if (request.client_id && !request.client_secret && opts.additionalParams?.client_id === void 0) {
774
+ delete request.client_id;
775
+ }
720
776
  return request;
721
777
  }
722
778
  throw new Error("Credential offer request follows neither pre-authorized code nor authorization code flow requirements.");
@@ -846,7 +902,7 @@ import { CodeChallengeMethod as CodeChallengeMethod2, convertJsonToURI as conver
846
902
  import { Loggers as Loggers4 } from "@sphereon/ssi-types";
847
903
 
848
904
  // lib/MetadataClient.ts
849
- import { determineSpecVersionFromOffer, determineVersionsFromIssuerMetadata, getIssuerFromCredentialOfferPayload as getIssuerFromCredentialOfferPayload3, OpenId4VCIVersion as OpenId4VCIVersion2, processSignedMetadata as processSignedMetadata2, WellKnownEndpoints as WellKnownEndpoints2 } from "@sphereon/oid4vci-common";
905
+ import { determineSpecVersionFromOffer, determineVersionsFromIssuerMetadata, getIssuerFromCredentialOfferPayload as getIssuerFromCredentialOfferPayload3, OpenId4VCIVersion as OpenId4VCIVersion2, processSignedMetadata as processSignedMetadata2, WellKnownEndpoints as WellKnownEndpoints3 } from "@sphereon/oid4vci-common";
850
906
  import { Loggers as Loggers3 } from "@sphereon/ssi-types";
851
907
  var logger3 = Loggers3.DEFAULT.get("sphereon:oid4vci:metadata");
852
908
  var MetadataClient = class _MetadataClient {
@@ -920,7 +976,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
920
976
  } else {
921
977
  throw new Error(`Issuer ${issuer} does not expose /.well-known/openid-credential-issuer`);
922
978
  }
923
- let response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints2.OPENID_CONFIGURATION, {
979
+ let response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints3.OPENID_CONFIGURATION, {
924
980
  errorOnNotFound: false
925
981
  });
926
982
  let authMetadata = response.successBody;
@@ -928,7 +984,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
928
984
  logger3.debug(`Issuer ${issuer} has OpenID Connect Server metadata in well-known location`);
929
985
  authorizationServerType = "OIDC";
930
986
  } else {
931
- response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints2.OAUTH_AS, {
987
+ response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints3.OAUTH_AS, {
932
988
  errorOnNotFound: false
933
989
  });
934
990
  authMetadata = response.successBody;
@@ -1029,7 +1085,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
1029
1085
  * @param opts
1030
1086
  */
1031
1087
  static async retrieveOpenID4VCIServerMetadata(issuerHost, opts) {
1032
- return retrieveWellknown(issuerHost, WellKnownEndpoints2.OPENID4VCI_ISSUER, {
1088
+ return retrieveWellknown(issuerHost, WellKnownEndpoints3.OPENID4VCI_ISSUER, {
1033
1089
  errorOnNotFound: opts?.errorOnNotFound === void 0 ? true : opts.errorOnNotFound
1034
1090
  });
1035
1091
  }
@@ -2273,7 +2329,7 @@ var CredentialRequestClientBuilder = class _CredentialRequestClientBuilder {
2273
2329
  };
2274
2330
 
2275
2331
  // lib/MetadataClientV1_0.ts
2276
- import { getIssuerFromCredentialOfferPayload as getIssuerFromCredentialOfferPayload6, processSignedMetadata as processSignedMetadata3, WellKnownEndpoints as WellKnownEndpoints3 } from "@sphereon/oid4vci-common";
2332
+ import { getIssuerFromCredentialOfferPayload as getIssuerFromCredentialOfferPayload6, processSignedMetadata as processSignedMetadata3, WellKnownEndpoints as WellKnownEndpoints4 } from "@sphereon/oid4vci-common";
2277
2333
  import { Loggers as Loggers7 } from "@sphereon/ssi-types";
2278
2334
  var logger7 = Loggers7.DEFAULT.get("sphereon:oid4vci:metadata");
2279
2335
  var MetadataClientV1_0 = class _MetadataClientV1_0 {
@@ -2321,7 +2377,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
2321
2377
  authorization_servers = credentialIssuerMetadata.authorization_servers;
2322
2378
  }
2323
2379
  }
2324
- let response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints3.OPENID_CONFIGURATION, {
2380
+ let response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints4.OPENID_CONFIGURATION, {
2325
2381
  errorOnNotFound: false
2326
2382
  });
2327
2383
  let authMetadata = response.successBody;
@@ -2329,7 +2385,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
2329
2385
  logger7.debug(`Issuer ${issuer} has OpenID Connect Server metadata in well-known location`);
2330
2386
  authorizationServerType = "OIDC";
2331
2387
  } else {
2332
- response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints3.OAUTH_AS, {
2388
+ response = await retrieveWellknown(authorization_servers[0], WellKnownEndpoints4.OAUTH_AS, {
2333
2389
  errorOnNotFound: false
2334
2390
  });
2335
2391
  authMetadata = response.successBody;
@@ -2445,7 +2501,7 @@ ${JSON.stringify(credentialIssuerMetadata)}`);
2445
2501
  };
2446
2502
  }
2447
2503
  static async retrieveOpenID4VCIServerMetadata(issuerHost, opts) {
2448
- return retrieveWellknown(issuerHost, WellKnownEndpoints3.OPENID4VCI_ISSUER, {
2504
+ return retrieveWellknown(issuerHost, WellKnownEndpoints4.OPENID4VCI_ISSUER, {
2449
2505
  errorOnNotFound: opts?.errorOnNotFound === void 0 ? true : opts.errorOnNotFound
2450
2506
  });
2451
2507
  }
@@ -3658,6 +3714,7 @@ export {
3658
3714
  createAuthorizationRequestUrl,
3659
3715
  createJwtBearerClientAssertion,
3660
3716
  createSignedAuthRequestWhenNeeded,
3717
+ determineWellknownLocations,
3661
3718
  generateMissingPKCEOpts,
3662
3719
  handleCredentialOfferUri,
3663
3720
  isUriEncoded,