oauth4webapi 2.16.0 → 2.17.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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # OAuth 2 / OpenID Connect for JavaScript Runtimes
1
+ # Low-Level OAuth 2 / OpenID Connect Client API for JavaScript Runtimes
2
2
 
3
3
  This software provides a collection of routines that can be used to build client modules for OAuth 2.1, OAuth 2.0 with the latest Security Best Current Practices (BCP), and FAPI 2.0, as well as OpenID Connect where applicable. The primary goal of this software is to promote secure and up-to-date best practices while using only the capabilities common to both browser and non-browser JavaScript runtimes.
4
4
 
package/build/index.d.ts CHANGED
@@ -444,63 +444,9 @@ export declare const jweDecrypt: unique symbol;
444
444
  */
445
445
  export declare const jwksCache: unique symbol;
446
446
  /**
447
- * When combined with {@link customFetch} (to use a Fetch API implementation that supports client
448
- * certificates) this can be used to target FAPI 2.0 profiles that utilize Mutual-TLS for either
449
- * client authentication or sender constraining. FAPI 1.0 Advanced profiles that use PAR and JARM
450
- * can also be targetted.
451
- *
452
- * When configured on an interface that extends {@link UseMTLSAliasOptions} this makes the client
453
- * prioritize an endpoint URL present in
454
- * {@link AuthorizationServer.mtls_endpoint_aliases `as.mtls_endpoint_aliases`}.
455
- *
456
- * @example
457
- *
458
- * (Node.js) Using [nodejs/undici](https://github.com/nodejs/undici) for Mutual-TLS Client
459
- * Authentication and Certificate-Bound Access Tokens support.
460
- *
461
- * ```ts
462
- * import * as undici from 'undici'
463
- * import * as oauth from 'oauth4webapi'
464
- *
465
- * // Prerequisites
466
- * let as!: oauth.AuthorizationServer
467
- * let client!: oauth.Client
468
- * let params!: URLSearchParams
469
- * let key!: string // PEM-encoded key
470
- * let cert!: string // PEM-encoded certificate
471
- *
472
- * const agent = new undici.Agent({ connect: { key, cert } })
473
- *
474
- * const response = await oauth.pushedAuthorizationRequest(as, client, params, {
475
- * [oauth.useMtlsAlias]: true,
476
- * [oauth.customFetch]: (...args) => undici.fetch(args[0], { ...args[1], dispatcher: agent }),
477
- * })
478
- * ```
479
- *
480
- * @example
481
- *
482
- * (Deno) Using Deno.createHttpClient API for Mutual-TLS Client Authentication and Certificate-Bound
483
- * Access Tokens support.
484
- *
485
- * ```ts
486
- * import * as oauth from 'oauth4webapi'
487
- *
488
- * // Prerequisites
489
- * let as!: oauth.AuthorizationServer
490
- * let client!: oauth.Client
491
- * let params!: URLSearchParams
492
- * let key!: string // PEM-encoded key
493
- * let cert!: string // PEM-encoded certificate
494
- *
495
- * const agent = Deno.createHttpClient({ key, cert })
496
- *
497
- * const response = await oauth.pushedAuthorizationRequest(as, client, params, {
498
- * [oauth.useMtlsAlias]: true,
499
- * [oauth.customFetch]: (...args) => fetch(args[0], { ...args[1], client: agent }),
500
- * })
501
- * ```
447
+ * @ignore
502
448
  *
503
- * @see [RFC 8705 - OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens](https://www.rfc-editor.org/rfc/rfc8705.html)
449
+ * @deprecated Use {@link Client.use_mtls_endpoint_aliases `client.use_mtls_endpoint_aliases`}.
504
450
  */
505
451
  export declare const useMtlsAlias: unique symbol;
506
452
  /**
@@ -882,6 +828,64 @@ export interface Client {
882
828
  * Default Maximum Authentication Age.
883
829
  */
884
830
  default_max_age?: number;
831
+ /**
832
+ * Indicates the requirement for a client to use mutual TLS endpoint aliases defined by the AS
833
+ * where present. Default is `false`.
834
+ *
835
+ * When combined with {@link customFetch} (to use a Fetch API implementation that supports client
836
+ * certificates) this can be used to target FAPI 2.0 profiles that utilize Mutual-TLS for either
837
+ * client authentication or sender constraining. FAPI 1.0 Advanced profiles that use PAR and JARM
838
+ * can also be targetted.
839
+ *
840
+ * @example
841
+ *
842
+ * (Node.js) Using [nodejs/undici](https://github.com/nodejs/undici) for Mutual-TLS Client
843
+ * Authentication and Certificate-Bound Access Tokens support.
844
+ *
845
+ * ```ts
846
+ * import * as undici from 'undici'
847
+ * import * as oauth from 'oauth4webapi'
848
+ *
849
+ * // Prerequisites
850
+ * let as!: oauth.AuthorizationServer
851
+ * let client!: oauth.Client & { use_mtls_endpoint_aliases: true }
852
+ * let params!: URLSearchParams
853
+ * let key!: string // PEM-encoded key
854
+ * let cert!: string // PEM-encoded certificate
855
+ *
856
+ * const agent = new undici.Agent({ connect: { key, cert } })
857
+ *
858
+ * const response = await oauth.pushedAuthorizationRequest(as, client, params, {
859
+ * [oauth.customFetch]: (...args) =>
860
+ * undici.fetch(args[0], { ...args[1], dispatcher: agent }),
861
+ * })
862
+ * ```
863
+ *
864
+ * @example
865
+ *
866
+ * (Deno) Using Deno.createHttpClient API for Mutual-TLS Client Authentication and
867
+ * Certificate-Bound Access Tokens support.
868
+ *
869
+ * ```ts
870
+ * import * as oauth from 'oauth4webapi'
871
+ *
872
+ * // Prerequisites
873
+ * let as!: oauth.AuthorizationServer
874
+ * let client!: oauth.Client & { use_mtls_endpoint_aliases: true }
875
+ * let params!: URLSearchParams
876
+ * let key!: string // PEM-encoded key
877
+ * let cert!: string // PEM-encoded certificate
878
+ *
879
+ * const agent = Deno.createHttpClient({ key, cert })
880
+ *
881
+ * const response = await oauth.pushedAuthorizationRequest(as, client, params, {
882
+ * [oauth.customFetch]: (...args) => fetch(args[0], { ...args[1], client: agent }),
883
+ * })
884
+ * ```
885
+ *
886
+ * @see [RFC 8705 - OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens](https://www.rfc-editor.org/rfc/rfc8705.html)
887
+ */
888
+ use_mtls_endpoint_aliases?: boolean;
885
889
  /**
886
890
  * See {@link clockSkew}.
887
891
  */
@@ -1006,7 +1010,7 @@ export declare function generateRandomState(): string;
1006
1010
  */
1007
1011
  export declare function generateRandomNonce(): string;
1008
1012
  /**
1009
- * Calculates the PKCE `code_verifier` value to send with an authorization request using the S256
1013
+ * Calculates the PKCE `code_challenge` value to send with an authorization request using the S256
1010
1014
  * PKCE Code Challenge Method transformation.
1011
1015
  *
1012
1016
  * @param codeVerifier `code_verifier` value generated e.g. from {@link generateRandomCodeVerifier}.
@@ -1048,9 +1052,16 @@ export interface DPoPRequestOptions {
1048
1052
  */
1049
1053
  DPoP?: DPoPOptions;
1050
1054
  }
1055
+ /**
1056
+ * @ignore
1057
+ *
1058
+ * @deprecated Use {@link Client.use_mtls_endpoint_aliases `client.use_mtls_endpoint_aliases`}.
1059
+ */
1051
1060
  export interface UseMTLSAliasOptions {
1052
1061
  /**
1053
- * See {@link useMtlsAlias}.
1062
+ * @ignore
1063
+ *
1064
+ * @deprecated Use {@link Client.use_mtls_endpoint_aliases `client.use_mtls_endpoint_aliases`}.
1054
1065
  */
1055
1066
  [useMtlsAlias]?: boolean;
1056
1067
  }
@@ -1976,19 +1987,19 @@ export declare const experimental_customFetch: symbol;
1976
1987
  /**
1977
1988
  * @ignore
1978
1989
  *
1979
- * @deprecated Use {@link useMtlsAlias}.
1990
+ * @deprecated Use {@link Client.use_mtls_endpoint_aliases `client.use_mtls_endpoint_aliases`}.
1980
1991
  */
1981
1992
  export declare const experimentalUseMtlsAlias: symbol;
1982
1993
  /**
1983
1994
  * @ignore
1984
1995
  *
1985
- * @deprecated Use {@link useMtlsAlias}.
1996
+ * @deprecated Use {@link Client.use_mtls_endpoint_aliases `client.use_mtls_endpoint_aliases`}.
1986
1997
  */
1987
1998
  export declare const experimental_useMtlsAlias: symbol;
1988
1999
  /**
1989
2000
  * @ignore
1990
2001
  *
1991
- * @deprecated Use {@link UseMTLSAliasOptions}.
2002
+ * @deprecated Use {@link Client.use_mtls_endpoint_aliases `client.use_mtls_endpoint_aliases`}.
1992
2003
  */
1993
2004
  export type ExperimentalUseMTLSAliasOptions = UseMTLSAliasOptions;
1994
2005
  /**
package/build/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  let USER_AGENT;
2
2
  if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
3
3
  const NAME = 'oauth4webapi';
4
- const VERSION = 'v2.16.0';
4
+ const VERSION = 'v2.17.0';
5
5
  USER_AGENT = `${NAME}/${VERSION}`;
6
6
  }
7
7
  function looseInstanceOf(input, expected) {
@@ -575,25 +575,31 @@ async function publicJwk(key) {
575
575
  jwkCache || (jwkCache = new WeakMap());
576
576
  return jwkCache.get(key) || getSetPublicJwkCache(key);
577
577
  }
578
- function validateEndpoint(value, endpoint, options) {
578
+ function validateEndpoint(value, endpoint, useMtlsAlias) {
579
579
  if (typeof value !== 'string') {
580
- if (options?.[useMtlsAlias]) {
580
+ if (useMtlsAlias) {
581
581
  throw new TypeError(`"as.mtls_endpoint_aliases.${endpoint}" must be a string`);
582
582
  }
583
583
  throw new TypeError(`"as.${endpoint}" must be a string`);
584
584
  }
585
585
  return new URL(value);
586
586
  }
587
- function resolveEndpoint(as, endpoint, options) {
588
- if (options?.[useMtlsAlias] && as.mtls_endpoint_aliases && endpoint in as.mtls_endpoint_aliases) {
589
- return validateEndpoint(as.mtls_endpoint_aliases[endpoint], endpoint, options);
587
+ function resolveEndpoint(as, endpoint, useMtlsAlias = false) {
588
+ if (useMtlsAlias && as.mtls_endpoint_aliases && endpoint in as.mtls_endpoint_aliases) {
589
+ return validateEndpoint(as.mtls_endpoint_aliases[endpoint], endpoint, useMtlsAlias);
590
590
  }
591
- return validateEndpoint(as[endpoint], endpoint);
591
+ return validateEndpoint(as[endpoint], endpoint, useMtlsAlias);
592
+ }
593
+ function alias(client, options) {
594
+ if (client.use_mtls_endpoint_aliases || options?.[useMtlsAlias]) {
595
+ return true;
596
+ }
597
+ return false;
592
598
  }
593
599
  export async function pushedAuthorizationRequest(as, client, parameters, options) {
594
600
  assertAs(as);
595
601
  assertClient(client);
596
- const url = resolveEndpoint(as, 'pushed_authorization_request_endpoint', options);
602
+ const url = resolveEndpoint(as, 'pushed_authorization_request_endpoint', alias(client, options));
597
603
  const body = new URLSearchParams(parameters);
598
604
  body.set('client_id', client.client_id);
599
605
  const headers = prepareHeaders(options?.headers);
@@ -726,7 +732,7 @@ export async function protectedResourceRequest(accessToken, method, url, headers
726
732
  export async function userInfoRequest(as, client, accessToken, options) {
727
733
  assertAs(as);
728
734
  assertClient(client);
729
- const url = resolveEndpoint(as, 'userinfo_endpoint', options);
735
+ const url = resolveEndpoint(as, 'userinfo_endpoint', alias(client, options));
730
736
  const headers = prepareHeaders(options?.headers);
731
737
  if (client.userinfo_signed_response_alg) {
732
738
  headers.set('accept', 'application/jwt');
@@ -917,7 +923,7 @@ async function authenticatedRequest(as, client, method, url, body, headers, opti
917
923
  }).then(processDpopNonce);
918
924
  }
919
925
  async function tokenEndpointRequest(as, client, grantType, parameters, options) {
920
- const url = resolveEndpoint(as, 'token_endpoint', options);
926
+ const url = resolveEndpoint(as, 'token_endpoint', alias(client, options));
921
927
  parameters.set('grant_type', grantType);
922
928
  const headers = prepareHeaders(options?.headers);
923
929
  headers.set('accept', 'application/json');
@@ -1228,7 +1234,7 @@ export async function revocationRequest(as, client, token, options) {
1228
1234
  if (!validateString(token)) {
1229
1235
  throw new TypeError('"token" must be a non-empty string');
1230
1236
  }
1231
- const url = resolveEndpoint(as, 'revocation_endpoint', options);
1237
+ const url = resolveEndpoint(as, 'revocation_endpoint', alias(client, options));
1232
1238
  const body = new URLSearchParams(options?.additionalParameters);
1233
1239
  body.set('token', token);
1234
1240
  const headers = prepareHeaders(options?.headers);
@@ -1259,7 +1265,7 @@ export async function introspectionRequest(as, client, token, options) {
1259
1265
  if (!validateString(token)) {
1260
1266
  throw new TypeError('"token" must be a non-empty string');
1261
1267
  }
1262
- const url = resolveEndpoint(as, 'introspection_endpoint', options);
1268
+ const url = resolveEndpoint(as, 'introspection_endpoint', alias(client, options));
1263
1269
  const body = new URLSearchParams(options?.additionalParameters);
1264
1270
  body.set('token', token);
1265
1271
  const headers = prepareHeaders(options?.headers);
@@ -1799,7 +1805,7 @@ async function importJwk(alg, jwk) {
1799
1805
  export async function deviceAuthorizationRequest(as, client, parameters, options) {
1800
1806
  assertAs(as);
1801
1807
  assertClient(client);
1802
- const url = resolveEndpoint(as, 'device_authorization_endpoint', options);
1808
+ const url = resolveEndpoint(as, 'device_authorization_endpoint', alias(client, options));
1803
1809
  const body = new URLSearchParams(parameters);
1804
1810
  body.set('client_id', client.client_id);
1805
1811
  const headers = prepareHeaders(options?.headers);
@@ -1875,7 +1881,10 @@ export async function generateKeyPair(alg, options) {
1875
1881
  publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
1876
1882
  });
1877
1883
  }
1878
- return (crypto.subtle.generateKey(algorithm, options?.extractable ?? false, ['sign', 'verify']));
1884
+ return crypto.subtle.generateKey(algorithm, options?.extractable ?? false, [
1885
+ 'sign',
1886
+ 'verify',
1887
+ ]);
1879
1888
  }
1880
1889
  function normalizeHtu(htu) {
1881
1890
  const url = new URL(htu);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oauth4webapi",
3
- "version": "2.16.0",
4
- "description": "OAuth 2 / OpenID Connect for JavaScript Runtimes",
3
+ "version": "2.17.0",
4
+ "description": "Low-Level OAuth 2 / OpenID Connect Client API for JavaScript Runtimes",
5
5
  "keywords": [
6
6
  "access token",
7
7
  "auth",