oauth4webapi 2.3.0 → 2.4.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.
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
- # OAuth 2 / OpenID Connect for Web Platform API JavaScript runtimes
1
+ # OAuth 2 / OpenID Connect for JavaScript Runtimes
2
2
 
3
- This software is a collection of routines upon which framework-specific client modules may be written. Its objective is to support and, where possible, enforce secure and current best practices using only capabilities common to Browser and Non-Browser JavaScript-based runtime environments.
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
 
5
- Target profiles of this software are OAuth 2.1, OAuth 2.0 complemented by the latest Security BCP, and FAPI 2.0. Where applicable OpenID Connect is also supported.
5
+ ## Features
6
6
 
7
- ## In Scope & Implemented
7
+ The following features are currently in scope and implemented in this software:
8
8
 
9
9
  - Authorization Server Metadata discovery
10
- - Authorization Code Flow (profiled under OpenID Connect 1.0, OAuth 2.0, OAuth 2.1, and FAPI 2.0), PKCE
10
+ - Authorization Code Flow (profiled under OpenID Connect 1.0, OAuth 2.0, OAuth 2.1, and FAPI 2.0), with PKCE
11
11
  - Refresh Token, Device Authorization, and Client Credentials Grants
12
12
  - Demonstrating Proof-of-Possession at the Application Layer (DPoP)
13
13
  - Token Introspection and Revocation
@@ -26,6 +26,8 @@ Target profiles of this software are OAuth 2.1, OAuth 2.0 complemented by the la
26
26
 
27
27
  ## Dependencies: 0
28
28
 
29
+ `oauth4webapi` has no dependencies and it exports tree-shakeable ESM.
30
+
29
31
  ## [Documentation](docs/README.md)
30
32
 
31
33
  ## [Examples](examples/README.md)
@@ -39,7 +41,7 @@ import * as oauth2 from 'oauth4webapi'
39
41
  **`example`** Deno import
40
42
 
41
43
  ```js
42
- import * as oauth2 from 'https://deno.land/x/oauth4webapi@v2.3.0/mod.ts'
44
+ import * as oauth2 from 'https://deno.land/x/oauth4webapi@v2.4.1/mod.ts'
43
45
  ```
44
46
 
45
47
  - Authorization Code Flow - OpenID Connect [source](examples/code.ts), or plain OAuth 2 [source](examples/oauth.ts)
@@ -54,9 +56,8 @@ import * as oauth2 from 'https://deno.land/x/oauth4webapi@v2.3.0/mod.ts'
54
56
 
55
57
  ## Supported Runtimes
56
58
 
57
- The supported JavaScript runtimes include ones that support the utilized Web API globals and standard built-in objects
59
+ The supported JavaScript runtimes include those that support the utilized Web API globals and standard built-in objects. These are _(but are not limited to)_:
58
60
 
59
- These are _(this is not an exhaustive list)_:
60
61
  - Browsers
61
62
  - Bun
62
63
  - Cloudflare Workers
@@ -67,6 +68,8 @@ These are _(this is not an exhaustive list)_:
67
68
 
68
69
  ## Out of scope
69
70
 
71
+ The following features are currently out of scope:
72
+
70
73
  - CommonJS
71
74
  - Implicit, Hybrid, and Resource Owner Password Credentials Flows
72
75
  - Mutual-TLS Client Authentication and Certificate-Bound Access Tokens
package/build/index.d.ts CHANGED
@@ -1,9 +1,13 @@
1
- type JsonObject = {
1
+ /** JSON Object */
2
+ export type JsonObject = {
2
3
  [Key in string]?: JsonValue;
3
4
  };
4
- type JsonArray = JsonValue[];
5
- type JsonPrimitive = string | number | boolean | null;
6
- type JsonValue = JsonPrimitive | JsonObject | JsonArray;
5
+ /** JSON Array */
6
+ export type JsonArray = JsonValue[];
7
+ /** JSON Primitives */
8
+ export type JsonPrimitive = string | number | boolean | null;
9
+ /** JSON Values */
10
+ export type JsonValue = JsonPrimitive | JsonObject | JsonArray;
7
11
  /**
8
12
  * Interface to pass an asymmetric private key and, optionally, its associated JWK Key ID to be
9
13
  * added as a `kid` JOSE Header Parameter.
@@ -45,72 +49,74 @@ export type ClientAuthenticationMethod = 'client_secret_basic' | 'client_secret_
45
49
  /**
46
50
  * Supported JWS `alg` Algorithm identifiers.
47
51
  *
48
- * @example CryptoKey algorithm for the `PS256`, `PS384`, or `PS512` JWS Algorithm Identifiers
52
+ * @example
53
+ *
54
+ * CryptoKey algorithm for the `PS256`, `PS384`, or `PS512` JWS Algorithm Identifiers
49
55
  *
50
56
  * ```ts
51
- * interface RSAPSSAlgorithm extends RsaHashedKeyAlgorithm {
57
+ * interface PS256 extends RsaHashedKeyAlgorithm {
52
58
  * name: 'RSA-PSS'
53
- * hash: { name: 'SHA-256' | 'SHA-384' | 'SHA-512' }
54
- * }
55
- *
56
- * interface PS256 extends RSAPSSAlgorithm {
57
- * hash: { name: 'SHA-256' }
59
+ * hash: 'SHA-256'
58
60
  * }
59
61
  *
60
- * interface PS384 extends RSAPSSAlgorithm {
61
- * hash: { name: 'SHA-384' }
62
+ * interface PS384 extends RsaHashedKeyAlgorithm {
63
+ * name: 'RSA-PSS'
64
+ * hash: 'SHA-384'
62
65
  * }
63
66
  *
64
- * interface PS512 extends RSAPSSAlgorithm {
65
- * hash: { name: 'SHA-512' }
67
+ * interface PS512 extends RsaHashedKeyAlgorithm {
68
+ * name: 'RSA-PSS'
69
+ * hash: 'SHA-512'
66
70
  * }
67
71
  * ```
68
72
  *
69
- * @example CryptoKey algorithm for the `ES256`, `ES384`, or `ES512` JWS Algorithm Identifiers
73
+ * @example
74
+ *
75
+ * CryptoKey algorithm for the `ES256`, `ES384`, or `ES512` JWS Algorithm Identifiers
70
76
  *
71
77
  * ```ts
72
- * interface ECDSAAlgorithm extends EcKeyAlgorithm {
78
+ * interface ES256 extends EcKeyAlgorithm {
73
79
  * name: 'ECDSA'
74
- * namedCurve: 'P-256' | 'P-384' | 'P-521'
75
- * }
76
- *
77
- * interface ES256 extends ECDSAAlgorithm {
78
80
  * namedCurve: 'P-256'
79
81
  * }
80
82
  *
81
- * interface ES384 extends ECDSAAlgorithm {
83
+ * interface ES384 extends EcKeyAlgorithm {
84
+ * name: 'ECDSA'
82
85
  * namedCurve: 'P-384'
83
86
  * }
84
87
  *
85
- * interface ES512 extends ECDSAAlgorithm {
88
+ * interface ES512 extends EcKeyAlgorithm {
89
+ * name: 'ECDSA'
86
90
  * namedCurve: 'P-521'
87
91
  * }
88
92
  * ```
89
93
  *
90
- * @example CryptoKey algorithm for the `RS256`, `RS384`, or `RS512` JWS Algorithm Identifiers
94
+ * @example
95
+ *
96
+ * CryptoKey algorithm for the `RS256`, `RS384`, or `RS512` JWS Algorithm Identifiers
91
97
  *
92
98
  * ```ts
93
- * interface ECDSAAlgorithm extends RsaHashedKeyAlgorithm {
99
+ * interface RS256 extends RsaHashedKeyAlgorithm {
94
100
  * name: 'RSASSA-PKCS1-v1_5'
95
- * hash: { name: 'SHA-256' | 'SHA-384' | 'SHA-512' }
96
- * }
97
- *
98
- * interface RS256 extends ECDSAAlgorithm {
99
- * hash: { name: 'SHA-256' }
101
+ * hash: 'SHA-256'
100
102
  * }
101
103
  *
102
- * interface RS384 extends ECDSAAlgorithm {
103
- * hash: { name: 'SHA-384' }
104
+ * interface RS384 extends RsaHashedKeyAlgorithm {
105
+ * name: 'RSASSA-PKCS1-v1_5'
106
+ * hash: 'SHA-384'
104
107
  * }
105
108
  *
106
- * interface RS512 extends ECDSAAlgorithm {
107
- * hash: { name: 'SHA-512' }
109
+ * interface RS512 extends RsaHashedKeyAlgorithm {
110
+ * name: 'RSASSA-PKCS1-v1_5'
111
+ * hash: 'SHA-512'
108
112
  * }
109
113
  * ```
110
114
  *
111
- * @example CryptoKey algorithm for the `EdDSA` JWS Algorithm Identifier (Experimental)
115
+ * @example
116
+ *
117
+ * CryptoKey algorithm for the `EdDSA` JWS Algorithm Identifier (Experimental)
112
118
  *
113
- * Runtime support for this algorithm is very limited, it depends on the [Secure Curves in the Web
119
+ * Runtime support for this algorithm is limited, it depends on the [Secure Curves in the Web
114
120
  * Cryptography API](https://wicg.github.io/webcrypto-secure-curves/) proposal which is yet to be
115
121
  * widely adopted. If the proposal changes this implementation will follow up with a minor release.
116
122
  *
@@ -479,7 +485,7 @@ export interface Client {
479
485
  *
480
486
  * @ignore during Documentation generation but part of the public API
481
487
  *
482
- * @example Tolerate 30 seconds clock skew when validating JWT claims like `exp` or `nbf`.
488
+ * @example Tolerate 30 seconds clock skew when validating JWT claims like exp or nbf.
483
489
  *
484
490
  * ```ts
485
491
  * const client: oauth.Client = {
@@ -492,18 +498,24 @@ export interface Client {
492
498
  [clockTolerance]?: number;
493
499
  [metadata: string]: JsonValue | undefined;
494
500
  }
501
+ /** @group Errors */
495
502
  export declare class UnsupportedOperationError extends Error {
496
503
  constructor(message?: string);
497
504
  }
505
+ /** @group Errors */
498
506
  export declare class OperationProcessingError extends Error {
499
- constructor(message: string);
507
+ constructor(message: string, options?: {
508
+ cause?: unknown;
509
+ });
500
510
  }
501
511
  export interface HttpRequestOptions {
502
512
  /**
503
513
  * An AbortSignal instance, or a factory returning one, to abort the HTTP Request(s) triggered by
504
514
  * this function's invocation.
505
515
  *
506
- * @example A 5000ms timeout AbortSignal for every request
516
+ * @example
517
+ *
518
+ * A 5000ms timeout AbortSignal for every request
507
519
  *
508
520
  * ```js
509
521
  * const signal = () => AbortSignal.timeout(5_000) // Note: AbortSignal.timeout may not yet be available in all runtimes.
@@ -530,6 +542,9 @@ export interface DiscoveryRequestOptions extends HttpRequestOptions {
530
542
  *
531
543
  * @param issuerIdentifier Issuer Identifier to resolve the well-known discovery URI for.
532
544
  *
545
+ * @group Authorization Server Metadata
546
+ * @group OpenID Connect (OIDC) Discovery
547
+ *
533
548
  * @see [RFC 8414 - OAuth 2.0 Authorization Server Metadata](https://www.rfc-editor.org/rfc/rfc8414.html#section-3)
534
549
  * @see [OpenID Connect Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig)
535
550
  */
@@ -543,6 +558,9 @@ export declare function discoveryRequest(issuerIdentifier: URL, options?: Discov
543
558
  *
544
559
  * @returns Resolves with the discovered Authorization Server Metadata.
545
560
  *
561
+ * @group Authorization Server Metadata
562
+ * @group OpenID Connect (OIDC) Discovery
563
+ *
546
564
  * @see [RFC 8414 - OAuth 2.0 Authorization Server Metadata](https://www.rfc-editor.org/rfc/rfc8414.html#section-3)
547
565
  * @see [OpenID Connect Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig)
548
566
  */
@@ -550,18 +568,27 @@ export declare function processDiscoveryResponse(expectedIssuerIdentifier: URL,
550
568
  /**
551
569
  * Generate random `code_verifier` value.
552
570
  *
571
+ * @group Utilities
572
+ * @group Authorization Code Grant
573
+ * @group Authorization Code Grant w/ OpenID Connect (OIDC)
574
+ * @group Proof Key for Code Exchange by OAuth Public Clients (PKCE)
575
+ *
553
576
  * @see [RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients (PKCE)](https://www.rfc-editor.org/rfc/rfc7636.html#section-4)
554
577
  */
555
578
  export declare function generateRandomCodeVerifier(): string;
556
579
  /**
557
580
  * Generate random `state` value.
558
581
  *
582
+ * @group Utilities
583
+ *
559
584
  * @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1.1)
560
585
  */
561
586
  export declare function generateRandomState(): string;
562
587
  /**
563
588
  * Generate random `nonce` value.
564
589
  *
590
+ * @group Utilities
591
+ *
565
592
  * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#IDToken)
566
593
  */
567
594
  export declare function generateRandomNonce(): string;
@@ -571,6 +598,10 @@ export declare function generateRandomNonce(): string;
571
598
  *
572
599
  * @param codeVerifier `code_verifier` value generated e.g. from {@link generateRandomCodeVerifier}.
573
600
  *
601
+ * @group Authorization Code Grant
602
+ * @group Authorization Code Grant w/ OpenID Connect (OIDC)
603
+ * @group Proof Key for Code Exchange by OAuth Public Clients (PKCE)
604
+ *
574
605
  * @see [RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients (PKCE)](https://www.rfc-editor.org/rfc/rfc7636.html#section-4)
575
606
  */
576
607
  export declare function calculatePKCECodeChallenge(codeVerifier: string): Promise<string>;
@@ -611,6 +642,10 @@ export interface PushedAuthorizationRequestOptions extends HttpRequestOptions, A
611
642
  * @param client Client Metadata.
612
643
  * @param privateKey Private key to sign the Request Object with.
613
644
  *
645
+ * @group Authorization Code Grant
646
+ * @group Authorization Code Grant w/ OpenID Connect (OIDC)
647
+ * @group JWT-Secured Authorization Request (JAR)
648
+ *
614
649
  * @see [RFC 9101 - The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR)](https://www.rfc-editor.org/rfc/rfc9101.html#name-request-object-2)
615
650
  */
616
651
  export declare function issueRequestObject(as: AuthorizationServer, client: Client, parameters: URLSearchParams | Record<string, string> | string[][], privateKey: CryptoKey | PrivateKey): Promise<string>;
@@ -622,8 +657,10 @@ export declare function issueRequestObject(as: AuthorizationServer, client: Clie
622
657
  * @param client Client Metadata.
623
658
  * @param parameters Authorization Request parameters.
624
659
  *
625
- * @see [RFC 9126 - OAuth 2.0 Pushed Authorization Requests](https://www.rfc-editor.org/rfc/rfc9126.html#name-pushed-authorization-reques)
626
- * @see [draft-ietf-oauth-dpop-16 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-16.html#name-dpop-with-pushed-authorizat)
660
+ * @group Pushed Authorization Requests (PAR)
661
+ *
662
+ * @see [RFC 9126 - OAuth 2.0 Pushed Authorization Requests (PAR)](https://www.rfc-editor.org/rfc/rfc9126.html#name-pushed-authorization-reques)
663
+ * @see [RFC 9449 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.rfc-editor.org/rfc/rfc9449.html#name-dpop-with-pushed-authorizat)
627
664
  */
628
665
  export declare function pushedAuthorizationRequest(as: AuthorizationServer, client: Client, parameters: URLSearchParams | Record<string, string> | string[][], options?: PushedAuthorizationRequestOptions): Promise<Response>;
629
666
  export interface PushedAuthorizationResponse {
@@ -639,7 +676,19 @@ export interface OAuth2Error {
639
676
  readonly scope?: string;
640
677
  readonly [parameter: string]: JsonValue | undefined;
641
678
  }
642
- /** A helper function used to determine if a response processing function returned an OAuth2Error. */
679
+ /**
680
+ * A helper function used to determine if a response processing function returned an OAuth2Error.
681
+ *
682
+ * @group Utilities
683
+ * @group Client Credentials Grant
684
+ * @group Device Authorization Grant
685
+ * @group Authorization Code Grant
686
+ * @group Authorization Code Grant w/ OpenID Connect (OIDC)
687
+ * @group Token Introspection
688
+ * @group Token Revocation
689
+ * @group Refreshing an Access Token
690
+ * @group Pushed Authorization Requests (PAR)
691
+ */
643
692
  export declare function isOAuth2Error(input?: ReturnTypes): input is OAuth2Error;
644
693
  export interface WWWAuthenticateChallengeParameters {
645
694
  readonly realm?: string;
@@ -649,11 +698,11 @@ export interface WWWAuthenticateChallengeParameters {
649
698
  readonly algs?: string;
650
699
  readonly scope?: string;
651
700
  /** NOTE: because the parameter names are case insensitive they are always returned lowercased */
652
- readonly [parameter: string]: string | undefined;
701
+ readonly [parameter: Lowercase<string>]: string | undefined;
653
702
  }
654
703
  export interface WWWAuthenticateChallenge {
655
704
  /** NOTE: because the value is case insensitive it is always returned lowercased */
656
- readonly scheme: string;
705
+ readonly scheme: Lowercase<string>;
657
706
  readonly parameters: WWWAuthenticateChallengeParameters;
658
707
  }
659
708
  /**
@@ -661,6 +710,17 @@ export interface WWWAuthenticateChallenge {
661
710
  *
662
711
  * @returns Array of {@link WWWAuthenticateChallenge} objects. Their order from the response is
663
712
  * preserved. `undefined` when there wasn't a `WWW-Authenticate` HTTP Header returned.
713
+ *
714
+ * @group Accessing Protected Resources
715
+ * @group Utilities
716
+ * @group Client Credentials Grant
717
+ * @group Device Authorization Grant
718
+ * @group Authorization Code Grant
719
+ * @group Authorization Code Grant w/ OpenID Connect (OIDC)
720
+ * @group Token Introspection
721
+ * @group Token Revocation
722
+ * @group Refreshing an Access Token
723
+ * @group Pushed Authorization Requests (PAR)
664
724
  */
665
725
  export declare function parseWwwAuthenticateChallenges(response: Response): WWWAuthenticateChallenge[] | undefined;
666
726
  /**
@@ -674,7 +734,10 @@ export declare function parseWwwAuthenticateChallenges(response: Response): WWWA
674
734
  * @returns Resolves with an object representing the parsed successful response, or an object
675
735
  * representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
676
736
  * OAuth 2.0 error was returned.
677
- * @see [RFC 9126 - OAuth 2.0 Pushed Authorization Requests](https://www.rfc-editor.org/rfc/rfc9126.html#name-pushed-authorization-reques)
737
+ *
738
+ * @group Pushed Authorization Requests (PAR)
739
+ *
740
+ * @see [RFC 9126 - OAuth 2.0 Pushed Authorization Requests (PAR)](https://www.rfc-editor.org/rfc/rfc9126.html#name-pushed-authorization-reques)
678
741
  */
679
742
  export declare function processPushedAuthorizationResponse(as: AuthorizationServer, client: Client, response: Response): Promise<PushedAuthorizationResponse | OAuth2Error>;
680
743
  export interface ProtectedResourceRequestOptions extends Omit<HttpRequestOptions, 'headers'>, DPoPRequestOptions {
@@ -700,8 +763,10 @@ export interface ProtectedResourceRequestOptions extends Omit<HttpRequestOptions
700
763
  * @param headers Headers for the request.
701
764
  * @param body Request body compatible with the Fetch API and the request's method.
702
765
  *
766
+ * @group Accessing Protected Resources
767
+ *
703
768
  * @see [RFC 6750 - The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://www.rfc-editor.org/rfc/rfc6750.html#section-2.1)
704
- * @see [draft-ietf-oauth-dpop-16 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-16.html#name-protected-resource-access)
769
+ * @see [RFC 9449 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.rfc-editor.org/rfc/rfc9449.html#name-protected-resource-access)
705
770
  */
706
771
  export declare function protectedResourceRequest(accessToken: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | string, url: URL, headers: Headers, body: RequestInit['body'], options?: ProtectedResourceRequestOptions): Promise<Response>;
707
772
  export interface UserInfoRequestOptions extends HttpRequestOptions, DPoPRequestOptions {
@@ -716,8 +781,11 @@ export interface UserInfoRequestOptions extends HttpRequestOptions, DPoPRequestO
716
781
  * @param client Client Metadata.
717
782
  * @param accessToken Access Token value.
718
783
  *
784
+ * @group Authorization Code Grant w/ OpenID Connect (OIDC)
785
+ * @group OpenID Connect (OIDC) UserInfo
786
+ *
719
787
  * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo)
720
- * @see [draft-ietf-oauth-dpop-16 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-16.html#name-protected-resource-access)
788
+ * @see [RFC 9449 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.rfc-editor.org/rfc/rfc9449.html#name-protected-resource-access)
721
789
  */
722
790
  export declare function userInfoRequest(as: AuthorizationServer, client: Client, accessToken: string, options?: UserInfoRequestOptions): Promise<Response>;
723
791
  export interface UserInfoAddress {
@@ -774,6 +842,10 @@ export declare const skipSubjectCheck: unique symbol;
774
842
  * @returns Resolves with an object representing the parsed successful response, or an object
775
843
  * representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
776
844
  * OAuth 2.0 error was returned.
845
+ *
846
+ * @group Authorization Code Grant w/ OpenID Connect (OIDC)
847
+ * @group OpenID Connect (OIDC) UserInfo
848
+ *
777
849
  * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo)
778
850
  */
779
851
  export declare function processUserInfoResponse(as: AuthorizationServer, client: Client, expectedSubject: string | typeof skipSubjectCheck, response: Response): Promise<UserInfoResponse>;
@@ -789,9 +861,11 @@ export interface TokenEndpointRequestOptions extends HttpRequestOptions, Authent
789
861
  * @param client Client Metadata.
790
862
  * @param refreshToken Refresh Token value.
791
863
  *
864
+ * @group Refreshing an Access Token
865
+ *
792
866
  * @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-6)
793
867
  * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens)
794
- * @see [draft-ietf-oauth-dpop-16 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-16.html#name-dpop-access-token-request)
868
+ * @see [RFC 9449 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.rfc-editor.org/rfc/rfc9449.html#name-dpop-access-token-request)
795
869
  */
796
870
  export declare function refreshTokenGrantRequest(as: AuthorizationServer, client: Client, refreshToken: string, options?: TokenEndpointRequestOptions): Promise<Response>;
797
871
  /**
@@ -800,6 +874,8 @@ export declare function refreshTokenGrantRequest(as: AuthorizationServer, client
800
874
  * @param ref Value previously resolved from {@link processAuthorizationCodeOpenIDResponse}.
801
875
  *
802
876
  * @returns JWT Claims Set from an ID Token.
877
+ *
878
+ * @group Authorization Code Grant w/ OpenID Connect (OIDC)
803
879
  */
804
880
  export declare function getValidatedIdTokenClaims(ref: OpenIDTokenEndpointResponse): IDToken;
805
881
  /**
@@ -823,6 +899,9 @@ export declare function getValidatedIdTokenClaims(ref: TokenEndpointResponse): I
823
899
  * @returns Resolves with an object representing the parsed successful response, or an object
824
900
  * representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
825
901
  * OAuth 2.0 error was returned.
902
+ *
903
+ * @group Refreshing an Access Token
904
+ *
826
905
  * @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-6)
827
906
  * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens)
828
907
  */
@@ -838,10 +917,13 @@ export declare function processRefreshTokenResponse(as: AuthorizationServer, cli
838
917
  * @param redirectUri `redirect_uri` value used in the authorization request.
839
918
  * @param codeVerifier PKCE `code_verifier` to send to the token endpoint.
840
919
  *
920
+ * @group Authorization Code Grant
921
+ * @group Authorization Code Grant w/ OpenID Connect (OIDC)
922
+ *
841
923
  * @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1)
842
924
  * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth)
843
925
  * @see [RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients (PKCE)](https://www.rfc-editor.org/rfc/rfc7636.html#section-4)
844
- * @see [draft-ietf-oauth-dpop-16 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-16.html#name-dpop-access-token-request)
926
+ * @see [RFC 9449 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.rfc-editor.org/rfc/rfc9449.html#name-dpop-access-token-request)
845
927
  */
846
928
  export declare function authorizationCodeGrantRequest(as: AuthorizationServer, client: Client, callbackParameters: URLSearchParams, redirectUri: string, codeVerifier: string, options?: TokenEndpointRequestOptions): Promise<Response>;
847
929
  interface JWTPayload {
@@ -871,7 +953,7 @@ export interface TokenEndpointResponse {
871
953
  readonly refresh_token?: string;
872
954
  readonly scope?: string;
873
955
  /** NOTE: because the value is case insensitive it is always returned lowercased */
874
- readonly token_type: string;
956
+ readonly token_type: 'bearer' | 'dpop' | Lowercase<string>;
875
957
  readonly [parameter: string]: JsonValue | undefined;
876
958
  }
877
959
  export interface OpenIDTokenEndpointResponse {
@@ -881,7 +963,7 @@ export interface OpenIDTokenEndpointResponse {
881
963
  readonly refresh_token?: string;
882
964
  readonly scope?: string;
883
965
  /** NOTE: because the value is case insensitive it is always returned lowercased */
884
- readonly token_type: string;
966
+ readonly token_type: 'bearer' | 'dpop' | Lowercase<string>;
885
967
  readonly [parameter: string]: JsonValue | undefined;
886
968
  }
887
969
  export interface OAuth2TokenEndpointResponse {
@@ -891,7 +973,7 @@ export interface OAuth2TokenEndpointResponse {
891
973
  readonly refresh_token?: string;
892
974
  readonly scope?: string;
893
975
  /** NOTE: because the value is case insensitive it is always returned lowercased */
894
- readonly token_type: string;
976
+ readonly token_type: 'bearer' | 'dpop' | Lowercase<string>;
895
977
  readonly [parameter: string]: JsonValue | undefined;
896
978
  }
897
979
  export interface ClientCredentialsGrantResponse {
@@ -899,7 +981,7 @@ export interface ClientCredentialsGrantResponse {
899
981
  readonly expires_in?: number;
900
982
  readonly scope?: string;
901
983
  /** NOTE: because the value is case insensitive it is always returned lowercased */
902
- readonly token_type: string;
984
+ readonly token_type: 'bearer' | 'dpop' | Lowercase<string>;
903
985
  readonly [parameter: string]: JsonValue | undefined;
904
986
  }
905
987
  /**
@@ -930,6 +1012,9 @@ export declare const skipAuthTimeCheck: unique symbol;
930
1012
  * @returns Resolves with an object representing the parsed successful response, or an object
931
1013
  * representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
932
1014
  * OAuth 2.0 error was returned.
1015
+ *
1016
+ * @group Authorization Code Grant w/ OpenID Connect (OIDC)
1017
+ *
933
1018
  * @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1)
934
1019
  * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth)
935
1020
  */
@@ -945,6 +1030,9 @@ export declare function processAuthorizationCodeOpenIDResponse(as: Authorization
945
1030
  * @returns Resolves with an object representing the parsed successful response, or an object
946
1031
  * representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
947
1032
  * OAuth 2.0 error was returned.
1033
+ *
1034
+ * @group Authorization Code Grant
1035
+ *
948
1036
  * @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1)
949
1037
  */
950
1038
  export declare function processAuthorizationCodeOAuth2Response(as: AuthorizationServer, client: Client, response: Response): Promise<OAuth2TokenEndpointResponse | OAuth2Error>;
@@ -957,8 +1045,10 @@ export interface ClientCredentialsGrantRequestOptions extends HttpRequestOptions
957
1045
  * @param as Authorization Server Metadata.
958
1046
  * @param client Client Metadata.
959
1047
  *
1048
+ * @group Client Credentials Grant
1049
+ *
960
1050
  * @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.4)
961
- * @see [draft-ietf-oauth-dpop-16 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-16.html#name-dpop-access-token-request)
1051
+ * @see [RFC 9449 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.rfc-editor.org/rfc/rfc9449.html#name-dpop-access-token-request)
962
1052
  */
963
1053
  export declare function clientCredentialsGrantRequest(as: AuthorizationServer, client: Client, parameters: URLSearchParams | Record<string, string> | string[][], options?: ClientCredentialsGrantRequestOptions): Promise<Response>;
964
1054
  /**
@@ -972,6 +1062,9 @@ export declare function clientCredentialsGrantRequest(as: AuthorizationServer, c
972
1062
  * @returns Resolves with an object representing the parsed successful response, or an object
973
1063
  * representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
974
1064
  * OAuth 2.0 error was returned.
1065
+ *
1066
+ * @group Client Credentials Grant
1067
+ *
975
1068
  * @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.4)
976
1069
  */
977
1070
  export declare function processClientCredentialsResponse(as: AuthorizationServer, client: Client, response: Response): Promise<ClientCredentialsGrantResponse | OAuth2Error>;
@@ -987,6 +1080,9 @@ export interface RevocationRequestOptions extends HttpRequestOptions, Authentica
987
1080
  * @param client Client Metadata.
988
1081
  * @param token Token to revoke. You can provide the `token_type_hint` parameter via
989
1082
  * {@link RevocationRequestOptions.additionalParameters options}.
1083
+ *
1084
+ * @group Token Revocation
1085
+ *
990
1086
  * @see [RFC 7009 - OAuth 2.0 Token Revocation](https://www.rfc-editor.org/rfc/rfc7009.html#section-2)
991
1087
  */
992
1088
  export declare function revocationRequest(as: AuthorizationServer, client: Client, token: string, options?: RevocationRequestOptions): Promise<Response>;
@@ -998,6 +1094,9 @@ export declare function revocationRequest(as: AuthorizationServer, client: Clien
998
1094
  *
999
1095
  * @returns Resolves with `undefined` when the request was successful, or an object representing an
1000
1096
  * OAuth 2.0 protocol style error.
1097
+ *
1098
+ * @group Token Revocation
1099
+ *
1001
1100
  * @see [RFC 7009 - OAuth 2.0 Token Revocation](https://www.rfc-editor.org/rfc/rfc7009.html#section-2)
1002
1101
  */
1003
1102
  export declare function processRevocationResponse(response: Response): Promise<undefined | OAuth2Error>;
@@ -1023,6 +1122,9 @@ export interface IntrospectionRequestOptions extends HttpRequestOptions, Authent
1023
1122
  * @param client Client Metadata.
1024
1123
  * @param token Token to introspect. You can provide the `token_type_hint` parameter via
1025
1124
  * {@link IntrospectionRequestOptions.additionalParameters options}.
1125
+ *
1126
+ * @group Token Introspection
1127
+ *
1026
1128
  * @see [RFC 7662 - OAuth 2.0 Token Introspection](https://www.rfc-editor.org/rfc/rfc7662.html#section-2)
1027
1129
  * @see [draft-ietf-oauth-jwt-introspection-response-12 - JWT Response for OAuth Token Introspection](https://www.ietf.org/archive/id/draft-ietf-oauth-jwt-introspection-response-12.html#section-4)
1028
1130
  */
@@ -1060,6 +1162,9 @@ export interface IntrospectionResponse {
1060
1162
  * @returns Resolves with an object representing the parsed successful response, or an object
1061
1163
  * representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
1062
1164
  * OAuth 2.0 error was returned.
1165
+ *
1166
+ * @group Token Introspection
1167
+ *
1063
1168
  * @see [RFC 7662 - OAuth 2.0 Token Introspection](https://www.rfc-editor.org/rfc/rfc7662.html#section-2)
1064
1169
  * @see [draft-ietf-oauth-jwt-introspection-response-12 - JWT Response for OAuth Token Introspection](https://www.ietf.org/archive/id/draft-ietf-oauth-jwt-introspection-response-12.html#section-5)
1065
1170
  */
@@ -1074,6 +1179,10 @@ export declare function processIntrospectionResponse(as: AuthorizationServer, cl
1074
1179
  *
1075
1180
  * @returns Validated Authorization Response parameters or Authorization Error Response.
1076
1181
  *
1182
+ * @group Authorization Code Grant
1183
+ * @group Authorization Code Grant w/ OpenID Connect (OIDC)
1184
+ * @group JWT Secured Authorization Response Mode for OAuth 2.0 (JARM)
1185
+ *
1077
1186
  * @see [JWT Secured Authorization Response Mode for OAuth 2.0 (JARM)](https://openid.net/specs/openid-financial-api-jarm.html)
1078
1187
  */
1079
1188
  export declare function validateJwtAuthResponse(as: AuthorizationServer, client: Client, parameters: URLSearchParams | URL, expectedState?: string | typeof expectNoState | typeof skipStateCheck, options?: HttpRequestOptions): Promise<URLSearchParams | OAuth2Error>;
@@ -1105,6 +1214,9 @@ export declare const expectNoState: unique symbol;
1105
1214
  *
1106
1215
  * @returns Validated Authorization Response parameters or Authorization Error Response.
1107
1216
  *
1217
+ * @group Authorization Code Grant
1218
+ * @group Authorization Code Grant w/ OpenID Connect (OIDC)
1219
+ *
1108
1220
  * @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1.2)
1109
1221
  * @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication)
1110
1222
  * @see [RFC 9207 - OAuth 2.0 Authorization Server Issuer Identification](https://www.rfc-editor.org/rfc/rfc9207.html)
@@ -1121,6 +1233,8 @@ export interface DeviceAuthorizationRequestOptions extends HttpRequestOptions, A
1121
1233
  * @param client Client Metadata.
1122
1234
  * @param parameters Device Authorization Request parameters.
1123
1235
  *
1236
+ * @group Device Authorization Grant
1237
+ *
1124
1238
  * @see [RFC 8628 - OAuth 2.0 Device Authorization Grant](https://www.rfc-editor.org/rfc/rfc8628.html#section-3.1)
1125
1239
  */
1126
1240
  export declare function deviceAuthorizationRequest(as: AuthorizationServer, client: Client, parameters: URLSearchParams | Record<string, string> | string[][], options?: DeviceAuthorizationRequestOptions): Promise<Response>;
@@ -1144,6 +1258,9 @@ export interface DeviceAuthorizationResponse {
1144
1258
  * @returns Resolves with an object representing the parsed successful response, or an object
1145
1259
  * representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
1146
1260
  * OAuth 2.0 error was returned.
1261
+ *
1262
+ * @group Device Authorization Grant
1263
+ *
1147
1264
  * @see [RFC 8628 - OAuth 2.0 Device Authorization Grant](https://www.rfc-editor.org/rfc/rfc8628.html#section-3.1)
1148
1265
  */
1149
1266
  export declare function processDeviceAuthorizationResponse(as: AuthorizationServer, client: Client, response: Response): Promise<DeviceAuthorizationResponse | OAuth2Error>;
@@ -1155,8 +1272,10 @@ export declare function processDeviceAuthorizationResponse(as: AuthorizationServ
1155
1272
  * @param client Client Metadata.
1156
1273
  * @param deviceCode Device Code.
1157
1274
  *
1275
+ * @group Device Authorization Grant
1276
+ *
1158
1277
  * @see [RFC 8628 - OAuth 2.0 Device Authorization Grant](https://www.rfc-editor.org/rfc/rfc8628.html#section-3.4)
1159
- * @see [draft-ietf-oauth-dpop-16 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-16.html#name-dpop-access-token-request)
1278
+ * @see [RFC 9449 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.rfc-editor.org/rfc/rfc9449.html#name-dpop-access-token-request)
1160
1279
  */
1161
1280
  export declare function deviceCodeGrantRequest(as: AuthorizationServer, client: Client, deviceCode: string, options?: TokenEndpointRequestOptions): Promise<Response>;
1162
1281
  /**
@@ -1170,6 +1289,9 @@ export declare function deviceCodeGrantRequest(as: AuthorizationServer, client:
1170
1289
  * @returns Resolves with an object representing the parsed successful response, or an object
1171
1290
  * representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
1172
1291
  * OAuth 2.0 error was returned.
1292
+ *
1293
+ * @group Device Authorization Grant
1294
+ *
1173
1295
  * @see [RFC 8628 - OAuth 2.0 Device Authorization Grant](https://www.rfc-editor.org/rfc/rfc8628.html#section-3.4)
1174
1296
  */
1175
1297
  export declare function processDeviceCodeResponse(as: AuthorizationServer, client: Client, response: Response): Promise<TokenEndpointResponse | OAuth2Error>;
@@ -1185,6 +1307,8 @@ export interface GenerateKeyPairOptions {
1185
1307
  * Generates a CryptoKeyPair for a given JWS `alg` Algorithm identifier.
1186
1308
  *
1187
1309
  * @param alg Supported JWS `alg` Algorithm identifier.
1310
+ *
1311
+ * @group Utilities
1188
1312
  */
1189
1313
  export declare function generateKeyPair(alg: JWSAlgorithm, options?: GenerateKeyPairOptions): Promise<CryptoKeyPair>;
1190
1314
  export {};
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.3.0';
4
+ const VERSION = 'v2.4.1';
5
5
  USER_AGENT = `${NAME}/${VERSION}`;
6
6
  }
7
7
  export const clockSkew = Symbol();
@@ -34,8 +34,8 @@ function decodeBase64Url(input) {
34
34
  }
35
35
  return bytes;
36
36
  }
37
- catch {
38
- throw new TypeError('The input to be decoded is not correctly encoded.');
37
+ catch (cause) {
38
+ throw new OPE('The input to be decoded is not correctly encoded.', { cause });
39
39
  }
40
40
  }
41
41
  function b64u(input) {
@@ -98,8 +98,8 @@ export class UnsupportedOperationError extends Error {
98
98
  }
99
99
  }
100
100
  export class OperationProcessingError extends Error {
101
- constructor(message) {
102
- super(message);
101
+ constructor(message, options) {
102
+ super(message, options);
103
103
  this.name = this.constructor.name;
104
104
  Error.captureStackTrace?.(this, this.constructor);
105
105
  }
@@ -194,12 +194,13 @@ export async function discoveryRequest(issuerIdentifier, options) {
194
194
  }
195
195
  const headers = prepareHeaders(options?.headers);
196
196
  headers.set('accept', 'application/json');
197
- return fetch(url.href, {
197
+ const request = new Request(url.href, {
198
198
  headers,
199
199
  method: 'GET',
200
200
  redirect: 'manual',
201
201
  signal: options?.signal ? signal(options.signal) : null,
202
- }).then(processDpopNonce);
202
+ });
203
+ return fetch(request).then(processDpopNonce);
203
204
  }
204
205
  function validateString(input) {
205
206
  return typeof input === 'string' && input.length !== 0;
@@ -219,8 +220,8 @@ export async function processDiscoveryResponse(expectedIssuerIdentifier, respons
219
220
  try {
220
221
  json = await response.json();
221
222
  }
222
- catch {
223
- throw new OPE('failed to parse "response" body as JSON');
223
+ catch (cause) {
224
+ throw new OPE('failed to parse "response" body as JSON', { cause });
224
225
  }
225
226
  if (!isJsonObject(json)) {
226
227
  throw new OPE('"response" body must be a top level object');
@@ -249,7 +250,7 @@ export async function calculatePKCECodeChallenge(codeVerifier) {
249
250
  if (!validateString(codeVerifier)) {
250
251
  throw new TypeError('"codeVerifier" must be a non-empty string');
251
252
  }
252
- return b64u(await crypto.subtle.digest({ name: 'SHA-256' }, buf(codeVerifier)));
253
+ return b64u(await crypto.subtle.digest('SHA-256', buf(codeVerifier)));
253
254
  }
254
255
  function getKeyAndKid(input) {
255
256
  if (input instanceof CryptoKey) {
@@ -473,8 +474,8 @@ export async function issueRequestObject(as, client, parameters, privateKey) {
473
474
  try {
474
475
  claims.claims = JSON.parse(value);
475
476
  }
476
- catch {
477
- throw new OPE('failed to parse the "claims" parameter as JSON');
477
+ catch (cause) {
478
+ throw new OPE('failed to parse the "claims" parameter as JSON', { cause });
478
479
  }
479
480
  if (!isJsonObject(claims.claims)) {
480
481
  throw new OPE('"claims" parameter must be a top level object');
@@ -511,9 +512,7 @@ async function dpopProofJwt(headers, options, url, htm, clockSkew, accessToken)
511
512
  htm,
512
513
  nonce,
513
514
  htu: `${url.origin}${url.pathname}`,
514
- ath: accessToken
515
- ? b64u(await crypto.subtle.digest({ name: 'SHA-256' }, buf(accessToken)))
516
- : undefined,
515
+ ath: accessToken ? b64u(await crypto.subtle.digest('SHA-256', buf(accessToken))) : undefined,
517
516
  }, privateKey);
518
517
  headers.set('dpop', proof);
519
518
  }
@@ -627,8 +626,8 @@ export async function processPushedAuthorizationResponse(as, client, response) {
627
626
  try {
628
627
  json = await response.json();
629
628
  }
630
- catch {
631
- throw new OPE('failed to parse "response" body as JSON');
629
+ catch (cause) {
630
+ throw new OPE('failed to parse "response" body as JSON', { cause });
632
631
  }
633
632
  if (!isJsonObject(json)) {
634
633
  throw new OPE('"response" body must be a top level object');
@@ -656,13 +655,14 @@ export async function protectedResourceRequest(accessToken, method, url, headers
656
655
  await dpopProofJwt(headers, options.DPoP, url, 'GET', getClockSkew({ [clockSkew]: options?.clockSkew }), accessToken);
657
656
  headers.set('authorization', `DPoP ${accessToken}`);
658
657
  }
659
- return fetch(url.href, {
658
+ const request = new Request(url.href, {
660
659
  body,
661
660
  headers,
662
661
  method,
663
662
  redirect: 'manual',
664
663
  signal: options?.signal ? signal(options.signal) : null,
665
- }).then(processDpopNonce);
664
+ });
665
+ return fetch(request).then(processDpopNonce);
666
666
  }
667
667
  export async function userInfoRequest(as, client, accessToken, options) {
668
668
  assertAs(as);
@@ -796,8 +796,8 @@ export async function processUserInfoResponse(as, client, expectedSubject, respo
796
796
  try {
797
797
  json = await response.json();
798
798
  }
799
- catch {
800
- throw new OPE('failed to parse "response" body as JSON');
799
+ catch (cause) {
800
+ throw new OPE('failed to parse "response" body as JSON', { cause });
801
801
  }
802
802
  }
803
803
  if (!isJsonObject(json)) {
@@ -822,13 +822,14 @@ export async function processUserInfoResponse(as, client, expectedSubject, respo
822
822
  async function authenticatedRequest(as, client, method, url, body, headers, options) {
823
823
  await clientAuthentication(as, client, body, headers, options?.clientPrivateKey);
824
824
  headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
825
- return fetch(url.href, {
825
+ const request = new Request(url.href, {
826
826
  body,
827
827
  headers,
828
828
  method,
829
829
  redirect: 'manual',
830
830
  signal: options?.signal ? signal(options.signal) : null,
831
- }).then(processDpopNonce);
831
+ });
832
+ return fetch(request).then(processDpopNonce);
832
833
  }
833
834
  async function tokenEndpointRequest(as, client, grantType, parameters, options) {
834
835
  if (typeof as.token_endpoint !== 'string') {
@@ -882,8 +883,8 @@ async function processGenericAccessTokenResponse(as, client, response, ignoreIdT
882
883
  try {
883
884
  json = await response.json();
884
885
  }
885
- catch {
886
- throw new OPE('failed to parse "response" body as JSON');
886
+ catch (cause) {
887
+ throw new OPE('failed to parse "response" body as JSON', { cause });
887
888
  }
888
889
  if (!isJsonObject(json)) {
889
890
  throw new OPE('"response" body must be a top level object');
@@ -1167,8 +1168,8 @@ export async function processIntrospectionResponse(as, client, response) {
1167
1168
  try {
1168
1169
  json = await response.json();
1169
1170
  }
1170
- catch {
1171
- throw new OPE('failed to parse "response" body as JSON');
1171
+ catch (cause) {
1172
+ throw new OPE('failed to parse "response" body as JSON', { cause });
1172
1173
  }
1173
1174
  if (!isJsonObject(json)) {
1174
1175
  throw new OPE('"response" body must be a top level object');
@@ -1188,12 +1189,13 @@ async function jwksRequest(as, options) {
1188
1189
  const headers = prepareHeaders(options?.headers);
1189
1190
  headers.set('accept', 'application/json');
1190
1191
  headers.append('accept', 'application/jwk-set+json');
1191
- return fetch(url.href, {
1192
+ const request = new Request(url.href, {
1192
1193
  headers,
1193
1194
  method: 'GET',
1194
1195
  redirect: 'manual',
1195
1196
  signal: options?.signal ? signal(options.signal) : null,
1196
- }).then(processDpopNonce);
1197
+ });
1198
+ return fetch(request).then(processDpopNonce);
1197
1199
  }
1198
1200
  async function processJwksResponse(response) {
1199
1201
  if (!(response instanceof Response)) {
@@ -1207,8 +1209,8 @@ async function processJwksResponse(response) {
1207
1209
  try {
1208
1210
  json = await response.json();
1209
1211
  }
1210
- catch {
1211
- throw new OPE('failed to parse "response" body as JSON');
1212
+ catch (cause) {
1213
+ throw new OPE('failed to parse "response" body as JSON', { cause });
1212
1214
  }
1213
1215
  if (!isJsonObject(json)) {
1214
1216
  throw new OPE('"response" body must be a top level object');
@@ -1274,7 +1276,7 @@ function keyToSubtle(key) {
1274
1276
  case 'ECDSA':
1275
1277
  return {
1276
1278
  name: key.algorithm.name,
1277
- hash: { name: ecdsaHashName(key.algorithm.namedCurve) },
1279
+ hash: ecdsaHashName(key.algorithm.namedCurve),
1278
1280
  };
1279
1281
  case 'RSA-PSS': {
1280
1282
  checkRsaKeyAlgorithm(key.algorithm);
@@ -1292,10 +1294,10 @@ function keyToSubtle(key) {
1292
1294
  }
1293
1295
  case 'RSASSA-PKCS1-v1_5':
1294
1296
  checkRsaKeyAlgorithm(key.algorithm);
1295
- return { name: key.algorithm.name };
1297
+ return key.algorithm.name;
1296
1298
  case 'Ed448':
1297
1299
  case 'Ed25519':
1298
- return { name: key.algorithm.name };
1300
+ return key.algorithm.name;
1299
1301
  }
1300
1302
  throw new UnsupportedOperationError();
1301
1303
  }
@@ -1312,8 +1314,8 @@ async function validateJwt(jws, checkAlg, getKey, clockSkew, clockTolerance) {
1312
1314
  try {
1313
1315
  header = JSON.parse(buf(b64u(protectedHeader)));
1314
1316
  }
1315
- catch {
1316
- throw new OPE('failed to parse JWT Header body as base64url encoded JSON');
1317
+ catch (cause) {
1318
+ throw new OPE('failed to parse JWT Header body as base64url encoded JSON', { cause });
1317
1319
  }
1318
1320
  if (!isJsonObject(header)) {
1319
1321
  throw new OPE('JWT Header must be a top level object');
@@ -1335,8 +1337,8 @@ async function validateJwt(jws, checkAlg, getKey, clockSkew, clockTolerance) {
1335
1337
  try {
1336
1338
  claims = JSON.parse(buf(b64u(payload)));
1337
1339
  }
1338
- catch {
1339
- throw new OPE('failed to parse JWT Payload body as base64url encoded JSON');
1340
+ catch (cause) {
1341
+ throw new OPE('failed to parse JWT Payload body as base64url encoded JSON', { cause });
1340
1342
  }
1341
1343
  if (!isJsonObject(claims)) {
1342
1344
  throw new OPE('JWT Payload must be a top level object');
@@ -1489,11 +1491,11 @@ function algToSubtle(alg, crv) {
1489
1491
  case 'PS256':
1490
1492
  case 'PS384':
1491
1493
  case 'PS512':
1492
- return { name: 'RSA-PSS', hash: { name: `SHA-${alg.slice(-3)}` } };
1494
+ return { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };
1493
1495
  case 'RS256':
1494
1496
  case 'RS384':
1495
1497
  case 'RS512':
1496
- return { name: 'RSASSA-PKCS1-v1_5', hash: { name: `SHA-${alg.slice(-3)}` } };
1498
+ return { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };
1497
1499
  case 'ES256':
1498
1500
  case 'ES384':
1499
1501
  return { name: 'ECDSA', namedCurve: `P-${alg.slice(-3)}` };
@@ -1502,9 +1504,8 @@ function algToSubtle(alg, crv) {
1502
1504
  case 'EdDSA': {
1503
1505
  switch (crv) {
1504
1506
  case 'Ed25519':
1505
- return { name: 'Ed25519' };
1506
1507
  case 'Ed448':
1507
- return { name: 'Ed448' };
1508
+ return crv;
1508
1509
  default:
1509
1510
  throw new UnsupportedOperationError();
1510
1511
  }
@@ -1548,8 +1549,8 @@ export async function processDeviceAuthorizationResponse(as, client, response) {
1548
1549
  try {
1549
1550
  json = await response.json();
1550
1551
  }
1551
- catch {
1552
- throw new OPE('failed to parse "response" body as JSON');
1552
+ catch (cause) {
1553
+ throw new OPE('failed to parse "response" body as JSON', { cause });
1553
1554
  }
1554
1555
  if (!isJsonObject(json)) {
1555
1556
  throw new OPE('"response" body must be a top level object');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oauth4webapi",
3
- "version": "2.3.0",
4
- "description": "OAuth 2 / OpenID Connect for Web Platform API JavaScript runtimes",
3
+ "version": "2.4.1",
4
+ "description": "OAuth 2 / OpenID Connect for JavaScript Runtimes",
5
5
  "keywords": [
6
6
  "auth",
7
7
  "authentication",
@@ -28,6 +28,7 @@
28
28
  "openid-connect",
29
29
  "openid",
30
30
  "vercel",
31
+ "workerd",
31
32
  "workers"
32
33
  ],
33
34
  "homepage": "https://github.com/panva/oauth4webapi",
@@ -58,26 +59,26 @@
58
59
  "tap:edge-runtime": "./tap/.edge-runtime.sh",
59
60
  "tap:electron": "./tap/.electron.sh",
60
61
  "tap:node": "bash -c './tap/.node.sh'",
61
- "tap:workers": "./tap/.workers.sh",
62
+ "tap:workerd": "./tap/.workerd.sh",
62
63
  "test": "bash -c 'source .node_flags.sh && ava'"
63
64
  },
64
65
  "devDependencies": {
65
- "@esbuild-kit/esm-loader": "^2.5.5",
66
- "@types/node": "^18.16.1",
67
- "@types/qunit": "^2.19.4",
68
- "ava": "^5.2.0",
69
- "edge-runtime": "^2.1.4",
70
- "esbuild": "^0.17.18",
71
- "jose": "^4.14.1",
72
- "patch-package": "^7.0.0",
73
- "prettier": "^2.8.8",
74
- "prettier-plugin-jsdoc": "^0.4.2",
75
- "qunit": "^2.19.4",
76
- "timekeeper": "^2.2.0",
77
- "typedoc": "^0.24.6",
78
- "typedoc-plugin-markdown": "^3.15.2",
79
- "typedoc-plugin-mdn-links": "^3.0.3",
80
- "typescript": "^5.0.4",
81
- "undici": "^5.22.0"
66
+ "@types/node": "^20.10.6",
67
+ "@types/qunit": "^2.19.9",
68
+ "ava": "^5.3.1",
69
+ "edge-runtime": "^2.5.7",
70
+ "esbuild": "^0.19.11",
71
+ "jose": "^5.2.0",
72
+ "patch-package": "^8.0.0",
73
+ "prettier": "^3.1.1",
74
+ "prettier-plugin-jsdoc": "^1.3.0",
75
+ "qunit": "^2.20.0",
76
+ "timekeeper": "^2.3.1",
77
+ "tsx": "^4.7.0",
78
+ "typedoc": "^0.25.6",
79
+ "typedoc-plugin-markdown": "^3.17.1",
80
+ "typedoc-plugin-mdn-links": "^3.1.10",
81
+ "typescript": "^5.3.3",
82
+ "undici": "^5.28.2"
82
83
  }
83
84
  }