oauth4webapi 2.2.4 → 2.4.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 +11 -8
- package/build/index.d.ts +50 -42
- package/build/index.js +33 -45
- package/package.json +21 -20
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# OAuth 2 / OpenID Connect for
|
|
1
|
+
# OAuth 2 / OpenID Connect for JavaScript Runtimes
|
|
2
2
|
|
|
3
|
-
This software
|
|
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
|
-
|
|
5
|
+
## Features
|
|
6
6
|
|
|
7
|
-
|
|
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.
|
|
44
|
+
import * as oauth2 from 'https://deno.land/x/oauth4webapi@v2.4.0/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.2.4/mod.ts'
|
|
|
54
56
|
|
|
55
57
|
## Supported Runtimes
|
|
56
58
|
|
|
57
|
-
The supported JavaScript runtimes include
|
|
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
|
@@ -48,41 +48,37 @@ export type ClientAuthenticationMethod = 'client_secret_basic' | 'client_secret_
|
|
|
48
48
|
* @example CryptoKey algorithm for the `PS256`, `PS384`, or `PS512` JWS Algorithm Identifiers
|
|
49
49
|
*
|
|
50
50
|
* ```ts
|
|
51
|
-
* interface
|
|
51
|
+
* interface PS256 extends RsaHashedKeyAlgorithm {
|
|
52
52
|
* name: 'RSA-PSS'
|
|
53
|
-
* hash:
|
|
53
|
+
* hash: 'SHA-256'
|
|
54
54
|
* }
|
|
55
55
|
*
|
|
56
|
-
* interface
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* interface PS384 extends RSAPSSAlgorithm {
|
|
61
|
-
* hash: { name: 'SHA-384' }
|
|
56
|
+
* interface PS384 extends RsaHashedKeyAlgorithm {
|
|
57
|
+
* name: 'RSA-PSS'
|
|
58
|
+
* hash: 'SHA-384'
|
|
62
59
|
* }
|
|
63
60
|
*
|
|
64
|
-
* interface PS512 extends
|
|
65
|
-
*
|
|
61
|
+
* interface PS512 extends RsaHashedKeyAlgorithm {
|
|
62
|
+
* name: 'RSA-PSS'
|
|
63
|
+
* hash: 'SHA-512'
|
|
66
64
|
* }
|
|
67
65
|
* ```
|
|
68
66
|
*
|
|
69
67
|
* @example CryptoKey algorithm for the `ES256`, `ES384`, or `ES512` JWS Algorithm Identifiers
|
|
70
68
|
*
|
|
71
69
|
* ```ts
|
|
72
|
-
* interface
|
|
70
|
+
* interface ES256 extends EcKeyAlgorithm {
|
|
73
71
|
* name: 'ECDSA'
|
|
74
|
-
* namedCurve: 'P-256' | 'P-384' | 'P-521'
|
|
75
|
-
* }
|
|
76
|
-
*
|
|
77
|
-
* interface ES256 extends ECDSAAlgorithm {
|
|
78
72
|
* namedCurve: 'P-256'
|
|
79
73
|
* }
|
|
80
74
|
*
|
|
81
|
-
* interface ES384 extends
|
|
75
|
+
* interface ES384 extends EcKeyAlgorithm {
|
|
76
|
+
* name: 'ECDSA'
|
|
82
77
|
* namedCurve: 'P-384'
|
|
83
78
|
* }
|
|
84
79
|
*
|
|
85
|
-
* interface ES512 extends
|
|
80
|
+
* interface ES512 extends EcKeyAlgorithm {
|
|
81
|
+
* name: 'ECDSA'
|
|
86
82
|
* namedCurve: 'P-521'
|
|
87
83
|
* }
|
|
88
84
|
* ```
|
|
@@ -90,21 +86,19 @@ export type ClientAuthenticationMethod = 'client_secret_basic' | 'client_secret_
|
|
|
90
86
|
* @example CryptoKey algorithm for the `RS256`, `RS384`, or `RS512` JWS Algorithm Identifiers
|
|
91
87
|
*
|
|
92
88
|
* ```ts
|
|
93
|
-
* interface
|
|
89
|
+
* interface RS256 extends RsaHashedKeyAlgorithm {
|
|
94
90
|
* name: 'RSASSA-PKCS1-v1_5'
|
|
95
|
-
* hash:
|
|
96
|
-
* }
|
|
97
|
-
*
|
|
98
|
-
* interface RS256 extends ECDSAAlgorithm {
|
|
99
|
-
* hash: { name: 'SHA-256' }
|
|
91
|
+
* hash: 'SHA-256'
|
|
100
92
|
* }
|
|
101
93
|
*
|
|
102
|
-
* interface RS384 extends
|
|
103
|
-
*
|
|
94
|
+
* interface RS384 extends RsaHashedKeyAlgorithm {
|
|
95
|
+
* name: 'RSASSA-PKCS1-v1_5'
|
|
96
|
+
* hash: 'SHA-384'
|
|
104
97
|
* }
|
|
105
98
|
*
|
|
106
|
-
* interface RS512 extends
|
|
107
|
-
*
|
|
99
|
+
* interface RS512 extends RsaHashedKeyAlgorithm {
|
|
100
|
+
* name: 'RSASSA-PKCS1-v1_5'
|
|
101
|
+
* hash: 'SHA-512'
|
|
108
102
|
* }
|
|
109
103
|
* ```
|
|
110
104
|
*
|
|
@@ -496,7 +490,9 @@ export declare class UnsupportedOperationError extends Error {
|
|
|
496
490
|
constructor(message?: string);
|
|
497
491
|
}
|
|
498
492
|
export declare class OperationProcessingError extends Error {
|
|
499
|
-
constructor(message: string
|
|
493
|
+
constructor(message: string, options?: {
|
|
494
|
+
cause?: unknown;
|
|
495
|
+
});
|
|
500
496
|
}
|
|
501
497
|
export interface HttpRequestOptions {
|
|
502
498
|
/**
|
|
@@ -613,7 +609,7 @@ export interface PushedAuthorizationRequestOptions extends HttpRequestOptions, A
|
|
|
613
609
|
*
|
|
614
610
|
* @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
611
|
*/
|
|
616
|
-
export declare function issueRequestObject(as: AuthorizationServer, client: Client, parameters: URLSearchParams, privateKey: CryptoKey | PrivateKey): Promise<string>;
|
|
612
|
+
export declare function issueRequestObject(as: AuthorizationServer, client: Client, parameters: URLSearchParams | Record<string, string> | string[][], privateKey: CryptoKey | PrivateKey): Promise<string>;
|
|
617
613
|
/**
|
|
618
614
|
* Performs a Pushed Authorization Request at the
|
|
619
615
|
* {@link AuthorizationServer.pushed_authorization_request_endpoint `as.pushed_authorization_request_endpoint`}.
|
|
@@ -623,9 +619,9 @@ export declare function issueRequestObject(as: AuthorizationServer, client: Clie
|
|
|
623
619
|
* @param parameters Authorization Request parameters.
|
|
624
620
|
*
|
|
625
621
|
* @see [RFC 9126 - OAuth 2.0 Pushed Authorization Requests](https://www.rfc-editor.org/rfc/rfc9126.html#name-pushed-authorization-reques)
|
|
626
|
-
* @see [
|
|
622
|
+
* @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
623
|
*/
|
|
628
|
-
export declare function pushedAuthorizationRequest(as: AuthorizationServer, client: Client, parameters: URLSearchParams, options?: PushedAuthorizationRequestOptions): Promise<Response>;
|
|
624
|
+
export declare function pushedAuthorizationRequest(as: AuthorizationServer, client: Client, parameters: URLSearchParams | Record<string, string> | string[][], options?: PushedAuthorizationRequestOptions): Promise<Response>;
|
|
629
625
|
export interface PushedAuthorizationResponse {
|
|
630
626
|
readonly request_uri: string;
|
|
631
627
|
readonly expires_in: number;
|
|
@@ -674,6 +670,7 @@ export declare function parseWwwAuthenticateChallenges(response: Response): WWWA
|
|
|
674
670
|
* @returns Resolves with an object representing the parsed successful response, or an object
|
|
675
671
|
* representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
|
|
676
672
|
* OAuth 2.0 error was returned.
|
|
673
|
+
*
|
|
677
674
|
* @see [RFC 9126 - OAuth 2.0 Pushed Authorization Requests](https://www.rfc-editor.org/rfc/rfc9126.html#name-pushed-authorization-reques)
|
|
678
675
|
*/
|
|
679
676
|
export declare function processPushedAuthorizationResponse(as: AuthorizationServer, client: Client, response: Response): Promise<PushedAuthorizationResponse | OAuth2Error>;
|
|
@@ -701,7 +698,7 @@ export interface ProtectedResourceRequestOptions extends Omit<HttpRequestOptions
|
|
|
701
698
|
* @param body Request body compatible with the Fetch API and the request's method.
|
|
702
699
|
*
|
|
703
700
|
* @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 [
|
|
701
|
+
* @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
702
|
*/
|
|
706
703
|
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
704
|
export interface UserInfoRequestOptions extends HttpRequestOptions, DPoPRequestOptions {
|
|
@@ -717,7 +714,7 @@ export interface UserInfoRequestOptions extends HttpRequestOptions, DPoPRequestO
|
|
|
717
714
|
* @param accessToken Access Token value.
|
|
718
715
|
*
|
|
719
716
|
* @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo)
|
|
720
|
-
* @see [
|
|
717
|
+
* @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
718
|
*/
|
|
722
719
|
export declare function userInfoRequest(as: AuthorizationServer, client: Client, accessToken: string, options?: UserInfoRequestOptions): Promise<Response>;
|
|
723
720
|
export interface UserInfoAddress {
|
|
@@ -774,12 +771,13 @@ export declare const skipSubjectCheck: unique symbol;
|
|
|
774
771
|
* @returns Resolves with an object representing the parsed successful response, or an object
|
|
775
772
|
* representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
|
|
776
773
|
* OAuth 2.0 error was returned.
|
|
774
|
+
*
|
|
777
775
|
* @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo)
|
|
778
776
|
*/
|
|
779
777
|
export declare function processUserInfoResponse(as: AuthorizationServer, client: Client, expectedSubject: string | typeof skipSubjectCheck, response: Response): Promise<UserInfoResponse>;
|
|
780
778
|
export interface TokenEndpointRequestOptions extends HttpRequestOptions, AuthenticatedRequestOptions, DPoPRequestOptions {
|
|
781
779
|
/** Any additional parameters to send. This cannot override existing parameter values. */
|
|
782
|
-
additionalParameters?: URLSearchParams;
|
|
780
|
+
additionalParameters?: URLSearchParams | Record<string, string> | string[][];
|
|
783
781
|
}
|
|
784
782
|
/**
|
|
785
783
|
* Performs a Refresh Token Grant request at the
|
|
@@ -791,7 +789,7 @@ export interface TokenEndpointRequestOptions extends HttpRequestOptions, Authent
|
|
|
791
789
|
*
|
|
792
790
|
* @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-6)
|
|
793
791
|
* @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens)
|
|
794
|
-
* @see [
|
|
792
|
+
* @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
793
|
*/
|
|
796
794
|
export declare function refreshTokenGrantRequest(as: AuthorizationServer, client: Client, refreshToken: string, options?: TokenEndpointRequestOptions): Promise<Response>;
|
|
797
795
|
/**
|
|
@@ -823,6 +821,7 @@ export declare function getValidatedIdTokenClaims(ref: TokenEndpointResponse): I
|
|
|
823
821
|
* @returns Resolves with an object representing the parsed successful response, or an object
|
|
824
822
|
* representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
|
|
825
823
|
* OAuth 2.0 error was returned.
|
|
824
|
+
*
|
|
826
825
|
* @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-6)
|
|
827
826
|
* @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens)
|
|
828
827
|
*/
|
|
@@ -841,7 +840,7 @@ export declare function processRefreshTokenResponse(as: AuthorizationServer, cli
|
|
|
841
840
|
* @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1)
|
|
842
841
|
* @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth)
|
|
843
842
|
* @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 [
|
|
843
|
+
* @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
844
|
*/
|
|
846
845
|
export declare function authorizationCodeGrantRequest(as: AuthorizationServer, client: Client, callbackParameters: URLSearchParams, redirectUri: string, codeVerifier: string, options?: TokenEndpointRequestOptions): Promise<Response>;
|
|
847
846
|
interface JWTPayload {
|
|
@@ -930,6 +929,7 @@ export declare const skipAuthTimeCheck: unique symbol;
|
|
|
930
929
|
* @returns Resolves with an object representing the parsed successful response, or an object
|
|
931
930
|
* representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
|
|
932
931
|
* OAuth 2.0 error was returned.
|
|
932
|
+
*
|
|
933
933
|
* @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1)
|
|
934
934
|
* @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth)
|
|
935
935
|
*/
|
|
@@ -945,6 +945,7 @@ export declare function processAuthorizationCodeOpenIDResponse(as: Authorization
|
|
|
945
945
|
* @returns Resolves with an object representing the parsed successful response, or an object
|
|
946
946
|
* representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
|
|
947
947
|
* OAuth 2.0 error was returned.
|
|
948
|
+
*
|
|
948
949
|
* @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1)
|
|
949
950
|
*/
|
|
950
951
|
export declare function processAuthorizationCodeOAuth2Response(as: AuthorizationServer, client: Client, response: Response): Promise<OAuth2TokenEndpointResponse | OAuth2Error>;
|
|
@@ -958,9 +959,9 @@ export interface ClientCredentialsGrantRequestOptions extends HttpRequestOptions
|
|
|
958
959
|
* @param client Client Metadata.
|
|
959
960
|
*
|
|
960
961
|
* @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.4)
|
|
961
|
-
* @see [
|
|
962
|
+
* @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
963
|
*/
|
|
963
|
-
export declare function clientCredentialsGrantRequest(as: AuthorizationServer, client: Client, parameters: URLSearchParams, options?: ClientCredentialsGrantRequestOptions): Promise<Response>;
|
|
964
|
+
export declare function clientCredentialsGrantRequest(as: AuthorizationServer, client: Client, parameters: URLSearchParams | Record<string, string> | string[][], options?: ClientCredentialsGrantRequestOptions): Promise<Response>;
|
|
964
965
|
/**
|
|
965
966
|
* Validates Client Credentials Grant Response instance to be one coming from the
|
|
966
967
|
* {@link AuthorizationServer.token_endpoint `as.token_endpoint`}.
|
|
@@ -972,12 +973,13 @@ export declare function clientCredentialsGrantRequest(as: AuthorizationServer, c
|
|
|
972
973
|
* @returns Resolves with an object representing the parsed successful response, or an object
|
|
973
974
|
* representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
|
|
974
975
|
* OAuth 2.0 error was returned.
|
|
976
|
+
*
|
|
975
977
|
* @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.4)
|
|
976
978
|
*/
|
|
977
979
|
export declare function processClientCredentialsResponse(as: AuthorizationServer, client: Client, response: Response): Promise<ClientCredentialsGrantResponse | OAuth2Error>;
|
|
978
980
|
export interface RevocationRequestOptions extends HttpRequestOptions, AuthenticatedRequestOptions {
|
|
979
981
|
/** Any additional parameters to send. This cannot override existing parameter values. */
|
|
980
|
-
additionalParameters?: URLSearchParams;
|
|
982
|
+
additionalParameters?: URLSearchParams | Record<string, string> | string[][];
|
|
981
983
|
}
|
|
982
984
|
/**
|
|
983
985
|
* Performs a Revocation Request at the
|
|
@@ -987,6 +989,7 @@ export interface RevocationRequestOptions extends HttpRequestOptions, Authentica
|
|
|
987
989
|
* @param client Client Metadata.
|
|
988
990
|
* @param token Token to revoke. You can provide the `token_type_hint` parameter via
|
|
989
991
|
* {@link RevocationRequestOptions.additionalParameters options}.
|
|
992
|
+
*
|
|
990
993
|
* @see [RFC 7009 - OAuth 2.0 Token Revocation](https://www.rfc-editor.org/rfc/rfc7009.html#section-2)
|
|
991
994
|
*/
|
|
992
995
|
export declare function revocationRequest(as: AuthorizationServer, client: Client, token: string, options?: RevocationRequestOptions): Promise<Response>;
|
|
@@ -998,12 +1001,13 @@ export declare function revocationRequest(as: AuthorizationServer, client: Clien
|
|
|
998
1001
|
*
|
|
999
1002
|
* @returns Resolves with `undefined` when the request was successful, or an object representing an
|
|
1000
1003
|
* OAuth 2.0 protocol style error.
|
|
1004
|
+
*
|
|
1001
1005
|
* @see [RFC 7009 - OAuth 2.0 Token Revocation](https://www.rfc-editor.org/rfc/rfc7009.html#section-2)
|
|
1002
1006
|
*/
|
|
1003
1007
|
export declare function processRevocationResponse(response: Response): Promise<undefined | OAuth2Error>;
|
|
1004
1008
|
export interface IntrospectionRequestOptions extends HttpRequestOptions, AuthenticatedRequestOptions {
|
|
1005
1009
|
/** Any additional parameters to send. This cannot override existing parameter values. */
|
|
1006
|
-
additionalParameters?: URLSearchParams;
|
|
1010
|
+
additionalParameters?: URLSearchParams | Record<string, string> | string[][];
|
|
1007
1011
|
/**
|
|
1008
1012
|
* Request a JWT Response from the
|
|
1009
1013
|
* {@link AuthorizationServer.introspection_endpoint `as.introspection_endpoint`}. Default is
|
|
@@ -1023,6 +1027,7 @@ export interface IntrospectionRequestOptions extends HttpRequestOptions, Authent
|
|
|
1023
1027
|
* @param client Client Metadata.
|
|
1024
1028
|
* @param token Token to introspect. You can provide the `token_type_hint` parameter via
|
|
1025
1029
|
* {@link IntrospectionRequestOptions.additionalParameters options}.
|
|
1030
|
+
*
|
|
1026
1031
|
* @see [RFC 7662 - OAuth 2.0 Token Introspection](https://www.rfc-editor.org/rfc/rfc7662.html#section-2)
|
|
1027
1032
|
* @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
1033
|
*/
|
|
@@ -1060,6 +1065,7 @@ export interface IntrospectionResponse {
|
|
|
1060
1065
|
* @returns Resolves with an object representing the parsed successful response, or an object
|
|
1061
1066
|
* representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
|
|
1062
1067
|
* OAuth 2.0 error was returned.
|
|
1068
|
+
*
|
|
1063
1069
|
* @see [RFC 7662 - OAuth 2.0 Token Introspection](https://www.rfc-editor.org/rfc/rfc7662.html#section-2)
|
|
1064
1070
|
* @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
1071
|
*/
|
|
@@ -1123,7 +1129,7 @@ export interface DeviceAuthorizationRequestOptions extends HttpRequestOptions, A
|
|
|
1123
1129
|
*
|
|
1124
1130
|
* @see [RFC 8628 - OAuth 2.0 Device Authorization Grant](https://www.rfc-editor.org/rfc/rfc8628.html#section-3.1)
|
|
1125
1131
|
*/
|
|
1126
|
-
export declare function deviceAuthorizationRequest(as: AuthorizationServer, client: Client, parameters: URLSearchParams, options?: DeviceAuthorizationRequestOptions): Promise<Response>;
|
|
1132
|
+
export declare function deviceAuthorizationRequest(as: AuthorizationServer, client: Client, parameters: URLSearchParams | Record<string, string> | string[][], options?: DeviceAuthorizationRequestOptions): Promise<Response>;
|
|
1127
1133
|
export interface DeviceAuthorizationResponse {
|
|
1128
1134
|
readonly device_code: string;
|
|
1129
1135
|
readonly user_code: string;
|
|
@@ -1144,6 +1150,7 @@ export interface DeviceAuthorizationResponse {
|
|
|
1144
1150
|
* @returns Resolves with an object representing the parsed successful response, or an object
|
|
1145
1151
|
* representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
|
|
1146
1152
|
* OAuth 2.0 error was returned.
|
|
1153
|
+
*
|
|
1147
1154
|
* @see [RFC 8628 - OAuth 2.0 Device Authorization Grant](https://www.rfc-editor.org/rfc/rfc8628.html#section-3.1)
|
|
1148
1155
|
*/
|
|
1149
1156
|
export declare function processDeviceAuthorizationResponse(as: AuthorizationServer, client: Client, response: Response): Promise<DeviceAuthorizationResponse | OAuth2Error>;
|
|
@@ -1156,7 +1163,7 @@ export declare function processDeviceAuthorizationResponse(as: AuthorizationServ
|
|
|
1156
1163
|
* @param deviceCode Device Code.
|
|
1157
1164
|
*
|
|
1158
1165
|
* @see [RFC 8628 - OAuth 2.0 Device Authorization Grant](https://www.rfc-editor.org/rfc/rfc8628.html#section-3.4)
|
|
1159
|
-
* @see [
|
|
1166
|
+
* @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
1167
|
*/
|
|
1161
1168
|
export declare function deviceCodeGrantRequest(as: AuthorizationServer, client: Client, deviceCode: string, options?: TokenEndpointRequestOptions): Promise<Response>;
|
|
1162
1169
|
/**
|
|
@@ -1170,6 +1177,7 @@ export declare function deviceCodeGrantRequest(as: AuthorizationServer, client:
|
|
|
1170
1177
|
* @returns Resolves with an object representing the parsed successful response, or an object
|
|
1171
1178
|
* representing an OAuth 2.0 protocol style error. Use {@link isOAuth2Error} to determine if an
|
|
1172
1179
|
* OAuth 2.0 error was returned.
|
|
1180
|
+
*
|
|
1173
1181
|
* @see [RFC 8628 - OAuth 2.0 Device Authorization Grant](https://www.rfc-editor.org/rfc/rfc8628.html#section-3.4)
|
|
1174
1182
|
*/
|
|
1175
1183
|
export declare function processDeviceCodeResponse(as: AuthorizationServer, client: Client, response: Response): Promise<TokenEndpointResponse | OAuth2Error>;
|
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.
|
|
4
|
+
const VERSION = 'v2.4.0';
|
|
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
|
|
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
|
}
|
|
@@ -219,8 +219,8 @@ export async function processDiscoveryResponse(expectedIssuerIdentifier, respons
|
|
|
219
219
|
try {
|
|
220
220
|
json = await response.json();
|
|
221
221
|
}
|
|
222
|
-
catch {
|
|
223
|
-
throw new OPE('failed to parse "response" body as JSON');
|
|
222
|
+
catch (cause) {
|
|
223
|
+
throw new OPE('failed to parse "response" body as JSON', { cause });
|
|
224
224
|
}
|
|
225
225
|
if (!isJsonObject(json)) {
|
|
226
226
|
throw new OPE('"response" body must be a top level object');
|
|
@@ -249,7 +249,7 @@ export async function calculatePKCECodeChallenge(codeVerifier) {
|
|
|
249
249
|
if (!validateString(codeVerifier)) {
|
|
250
250
|
throw new TypeError('"codeVerifier" must be a non-empty string');
|
|
251
251
|
}
|
|
252
|
-
return b64u(await crypto.subtle.digest(
|
|
252
|
+
return b64u(await crypto.subtle.digest('SHA-256', buf(codeVerifier)));
|
|
253
253
|
}
|
|
254
254
|
function getKeyAndKid(input) {
|
|
255
255
|
if (input instanceof CryptoKey) {
|
|
@@ -443,9 +443,6 @@ async function jwt(header, claimsSet, key) {
|
|
|
443
443
|
export async function issueRequestObject(as, client, parameters, privateKey) {
|
|
444
444
|
assertAs(as);
|
|
445
445
|
assertClient(client);
|
|
446
|
-
if (!(parameters instanceof URLSearchParams)) {
|
|
447
|
-
throw new TypeError('"parameters" must be an instance of URLSearchParams');
|
|
448
|
-
}
|
|
449
446
|
parameters = new URLSearchParams(parameters);
|
|
450
447
|
const { key, kid } = getKeyAndKid(privateKey);
|
|
451
448
|
if (!isPrivateKey(key)) {
|
|
@@ -476,8 +473,8 @@ export async function issueRequestObject(as, client, parameters, privateKey) {
|
|
|
476
473
|
try {
|
|
477
474
|
claims.claims = JSON.parse(value);
|
|
478
475
|
}
|
|
479
|
-
catch {
|
|
480
|
-
throw new OPE('failed to parse the "claims" parameter as JSON');
|
|
476
|
+
catch (cause) {
|
|
477
|
+
throw new OPE('failed to parse the "claims" parameter as JSON', { cause });
|
|
481
478
|
}
|
|
482
479
|
if (!isJsonObject(claims.claims)) {
|
|
483
480
|
throw new OPE('"claims" parameter must be a top level object');
|
|
@@ -514,9 +511,7 @@ async function dpopProofJwt(headers, options, url, htm, clockSkew, accessToken)
|
|
|
514
511
|
htm,
|
|
515
512
|
nonce,
|
|
516
513
|
htu: `${url.origin}${url.pathname}`,
|
|
517
|
-
ath: accessToken
|
|
518
|
-
? b64u(await crypto.subtle.digest({ name: 'SHA-256' }, buf(accessToken)))
|
|
519
|
-
: undefined,
|
|
514
|
+
ath: accessToken ? b64u(await crypto.subtle.digest('SHA-256', buf(accessToken))) : undefined,
|
|
520
515
|
}, privateKey);
|
|
521
516
|
headers.set('dpop', proof);
|
|
522
517
|
}
|
|
@@ -534,9 +529,6 @@ async function publicJwk(key) {
|
|
|
534
529
|
export async function pushedAuthorizationRequest(as, client, parameters, options) {
|
|
535
530
|
assertAs(as);
|
|
536
531
|
assertClient(client);
|
|
537
|
-
if (!(parameters instanceof URLSearchParams)) {
|
|
538
|
-
throw new TypeError('"parameters" must be an instance of URLSearchParams');
|
|
539
|
-
}
|
|
540
532
|
if (typeof as.pushed_authorization_request_endpoint !== 'string') {
|
|
541
533
|
throw new TypeError('"as.pushed_authorization_request_endpoint" must be a string');
|
|
542
534
|
}
|
|
@@ -633,8 +625,8 @@ export async function processPushedAuthorizationResponse(as, client, response) {
|
|
|
633
625
|
try {
|
|
634
626
|
json = await response.json();
|
|
635
627
|
}
|
|
636
|
-
catch {
|
|
637
|
-
throw new OPE('failed to parse "response" body as JSON');
|
|
628
|
+
catch (cause) {
|
|
629
|
+
throw new OPE('failed to parse "response" body as JSON', { cause });
|
|
638
630
|
}
|
|
639
631
|
if (!isJsonObject(json)) {
|
|
640
632
|
throw new OPE('"response" body must be a top level object');
|
|
@@ -802,8 +794,8 @@ export async function processUserInfoResponse(as, client, expectedSubject, respo
|
|
|
802
794
|
try {
|
|
803
795
|
json = await response.json();
|
|
804
796
|
}
|
|
805
|
-
catch {
|
|
806
|
-
throw new OPE('failed to parse "response" body as JSON');
|
|
797
|
+
catch (cause) {
|
|
798
|
+
throw new OPE('failed to parse "response" body as JSON', { cause });
|
|
807
799
|
}
|
|
808
800
|
}
|
|
809
801
|
if (!isJsonObject(json)) {
|
|
@@ -888,8 +880,8 @@ async function processGenericAccessTokenResponse(as, client, response, ignoreIdT
|
|
|
888
880
|
try {
|
|
889
881
|
json = await response.json();
|
|
890
882
|
}
|
|
891
|
-
catch {
|
|
892
|
-
throw new OPE('failed to parse "response" body as JSON');
|
|
883
|
+
catch (cause) {
|
|
884
|
+
throw new OPE('failed to parse "response" body as JSON', { cause });
|
|
893
885
|
}
|
|
894
886
|
if (!isJsonObject(json)) {
|
|
895
887
|
throw new OPE('"response" body must be a top level object');
|
|
@@ -1173,8 +1165,8 @@ export async function processIntrospectionResponse(as, client, response) {
|
|
|
1173
1165
|
try {
|
|
1174
1166
|
json = await response.json();
|
|
1175
1167
|
}
|
|
1176
|
-
catch {
|
|
1177
|
-
throw new OPE('failed to parse "response" body as JSON');
|
|
1168
|
+
catch (cause) {
|
|
1169
|
+
throw new OPE('failed to parse "response" body as JSON', { cause });
|
|
1178
1170
|
}
|
|
1179
1171
|
if (!isJsonObject(json)) {
|
|
1180
1172
|
throw new OPE('"response" body must be a top level object');
|
|
@@ -1213,8 +1205,8 @@ async function processJwksResponse(response) {
|
|
|
1213
1205
|
try {
|
|
1214
1206
|
json = await response.json();
|
|
1215
1207
|
}
|
|
1216
|
-
catch {
|
|
1217
|
-
throw new OPE('failed to parse "response" body as JSON');
|
|
1208
|
+
catch (cause) {
|
|
1209
|
+
throw new OPE('failed to parse "response" body as JSON', { cause });
|
|
1218
1210
|
}
|
|
1219
1211
|
if (!isJsonObject(json)) {
|
|
1220
1212
|
throw new OPE('"response" body must be a top level object');
|
|
@@ -1280,7 +1272,7 @@ function keyToSubtle(key) {
|
|
|
1280
1272
|
case 'ECDSA':
|
|
1281
1273
|
return {
|
|
1282
1274
|
name: key.algorithm.name,
|
|
1283
|
-
hash:
|
|
1275
|
+
hash: ecdsaHashName(key.algorithm.namedCurve),
|
|
1284
1276
|
};
|
|
1285
1277
|
case 'RSA-PSS': {
|
|
1286
1278
|
checkRsaKeyAlgorithm(key.algorithm);
|
|
@@ -1298,10 +1290,10 @@ function keyToSubtle(key) {
|
|
|
1298
1290
|
}
|
|
1299
1291
|
case 'RSASSA-PKCS1-v1_5':
|
|
1300
1292
|
checkRsaKeyAlgorithm(key.algorithm);
|
|
1301
|
-
return
|
|
1293
|
+
return key.algorithm.name;
|
|
1302
1294
|
case 'Ed448':
|
|
1303
1295
|
case 'Ed25519':
|
|
1304
|
-
return
|
|
1296
|
+
return key.algorithm.name;
|
|
1305
1297
|
}
|
|
1306
1298
|
throw new UnsupportedOperationError();
|
|
1307
1299
|
}
|
|
@@ -1318,8 +1310,8 @@ async function validateJwt(jws, checkAlg, getKey, clockSkew, clockTolerance) {
|
|
|
1318
1310
|
try {
|
|
1319
1311
|
header = JSON.parse(buf(b64u(protectedHeader)));
|
|
1320
1312
|
}
|
|
1321
|
-
catch {
|
|
1322
|
-
throw new OPE('failed to parse JWT Header body as base64url encoded JSON');
|
|
1313
|
+
catch (cause) {
|
|
1314
|
+
throw new OPE('failed to parse JWT Header body as base64url encoded JSON', { cause });
|
|
1323
1315
|
}
|
|
1324
1316
|
if (!isJsonObject(header)) {
|
|
1325
1317
|
throw new OPE('JWT Header must be a top level object');
|
|
@@ -1341,8 +1333,8 @@ async function validateJwt(jws, checkAlg, getKey, clockSkew, clockTolerance) {
|
|
|
1341
1333
|
try {
|
|
1342
1334
|
claims = JSON.parse(buf(b64u(payload)));
|
|
1343
1335
|
}
|
|
1344
|
-
catch {
|
|
1345
|
-
throw new OPE('failed to parse JWT Payload body as base64url encoded JSON');
|
|
1336
|
+
catch (cause) {
|
|
1337
|
+
throw new OPE('failed to parse JWT Payload body as base64url encoded JSON', { cause });
|
|
1346
1338
|
}
|
|
1347
1339
|
if (!isJsonObject(claims)) {
|
|
1348
1340
|
throw new OPE('JWT Payload must be a top level object');
|
|
@@ -1495,11 +1487,11 @@ function algToSubtle(alg, crv) {
|
|
|
1495
1487
|
case 'PS256':
|
|
1496
1488
|
case 'PS384':
|
|
1497
1489
|
case 'PS512':
|
|
1498
|
-
return { name: 'RSA-PSS', hash:
|
|
1490
|
+
return { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };
|
|
1499
1491
|
case 'RS256':
|
|
1500
1492
|
case 'RS384':
|
|
1501
1493
|
case 'RS512':
|
|
1502
|
-
return { name: 'RSASSA-PKCS1-v1_5', hash:
|
|
1494
|
+
return { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };
|
|
1503
1495
|
case 'ES256':
|
|
1504
1496
|
case 'ES384':
|
|
1505
1497
|
return { name: 'ECDSA', namedCurve: `P-${alg.slice(-3)}` };
|
|
@@ -1508,9 +1500,8 @@ function algToSubtle(alg, crv) {
|
|
|
1508
1500
|
case 'EdDSA': {
|
|
1509
1501
|
switch (crv) {
|
|
1510
1502
|
case 'Ed25519':
|
|
1511
|
-
return { name: 'Ed25519' };
|
|
1512
1503
|
case 'Ed448':
|
|
1513
|
-
return
|
|
1504
|
+
return crv;
|
|
1514
1505
|
default:
|
|
1515
1506
|
throw new UnsupportedOperationError();
|
|
1516
1507
|
}
|
|
@@ -1526,9 +1517,6 @@ async function importJwk(alg, jwk) {
|
|
|
1526
1517
|
export async function deviceAuthorizationRequest(as, client, parameters, options) {
|
|
1527
1518
|
assertAs(as);
|
|
1528
1519
|
assertClient(client);
|
|
1529
|
-
if (!(parameters instanceof URLSearchParams)) {
|
|
1530
|
-
throw new TypeError('"parameters" must be an instance of URLSearchParams');
|
|
1531
|
-
}
|
|
1532
1520
|
if (typeof as.device_authorization_endpoint !== 'string') {
|
|
1533
1521
|
throw new TypeError('"as.device_authorization_endpoint" must be a string');
|
|
1534
1522
|
}
|
|
@@ -1557,8 +1545,8 @@ export async function processDeviceAuthorizationResponse(as, client, response) {
|
|
|
1557
1545
|
try {
|
|
1558
1546
|
json = await response.json();
|
|
1559
1547
|
}
|
|
1560
|
-
catch {
|
|
1561
|
-
throw new OPE('failed to parse "response" body as JSON');
|
|
1548
|
+
catch (cause) {
|
|
1549
|
+
throw new OPE('failed to parse "response" body as JSON', { cause });
|
|
1562
1550
|
}
|
|
1563
1551
|
if (!isJsonObject(json)) {
|
|
1564
1552
|
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.
|
|
4
|
-
"description": "OAuth 2 / OpenID Connect for
|
|
3
|
+
"version": "2.4.0",
|
|
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:
|
|
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.
|
|
66
|
-
"@types/node": "^
|
|
67
|
-
"@types/qunit": "^2.19.
|
|
68
|
-
"ava": "^5.
|
|
69
|
-
"edge-runtime": "^2.
|
|
70
|
-
"esbuild": "^0.
|
|
71
|
-
"jose": "^
|
|
72
|
-
"patch-package": "^
|
|
73
|
-
"prettier": "^
|
|
74
|
-
"prettier-plugin-jsdoc": "^
|
|
75
|
-
"qunit": "^2.
|
|
76
|
-
"timekeeper": "^2.
|
|
77
|
-
"typedoc": "^0.
|
|
78
|
-
"typedoc-plugin-markdown": "^3.
|
|
79
|
-
"typedoc-plugin-mdn-links": "^3.0
|
|
80
|
-
"typescript": "^5.
|
|
81
|
-
"undici": "^5.
|
|
66
|
+
"@esbuild-kit/esm-loader": "^2.6.5",
|
|
67
|
+
"@types/node": "^20.9.0",
|
|
68
|
+
"@types/qunit": "^2.19.8",
|
|
69
|
+
"ava": "^5.3.1",
|
|
70
|
+
"edge-runtime": "^2.5.7",
|
|
71
|
+
"esbuild": "^0.19.5",
|
|
72
|
+
"jose": "^5.1.1",
|
|
73
|
+
"patch-package": "^8.0.0",
|
|
74
|
+
"prettier": "^3.1.0",
|
|
75
|
+
"prettier-plugin-jsdoc": "^1.1.1",
|
|
76
|
+
"qunit": "^2.20.0",
|
|
77
|
+
"timekeeper": "^2.3.1",
|
|
78
|
+
"typedoc": "^0.25.3",
|
|
79
|
+
"typedoc-plugin-markdown": "^3.17.1",
|
|
80
|
+
"typedoc-plugin-mdn-links": "^3.1.0",
|
|
81
|
+
"typescript": "^5.2.2",
|
|
82
|
+
"undici": "^5.27.2"
|
|
82
83
|
}
|
|
83
84
|
}
|