oauth4webapi 1.4.1 → 2.0.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 +1 -2
- package/build/index.d.ts +22 -142
- package/build/index.js +50 -67
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ import * as oauth2 from 'oauth4webapi'
|
|
|
39
39
|
**`example`** Deno import
|
|
40
40
|
|
|
41
41
|
```js
|
|
42
|
-
import * as oauth2 from 'https://deno.land/x/oauth4webapi/mod.ts'
|
|
42
|
+
import * as oauth2 from 'https://deno.land/x/oauth4webapi@v2.0.1/mod.ts'
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
- Authorization Code Flow - OpenID Connect [source](examples/code.ts), or plain OAuth 2 [source](examples/oauth.ts)
|
|
@@ -71,5 +71,4 @@ These are _(this is not an exhaustive list)_:
|
|
|
71
71
|
- Implicit, Hybrid, and Resource Owner Password Credentials Flows
|
|
72
72
|
- Mutual-TLS Client Authentication and Certificate-Bound Access Tokens
|
|
73
73
|
- JSON Web Encryption (JWE)
|
|
74
|
-
- JSON Web Signature (JWS) rarely used algorithms and HMAC
|
|
75
74
|
- Automatic polyfills of any kind
|
package/build/index.d.ts
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
export declare type JsonObject = {
|
|
1
|
+
declare type JsonObject = {
|
|
3
2
|
[Key in string]?: JsonValue;
|
|
4
3
|
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export declare type JsonPrimitive = string | number | boolean | null;
|
|
9
|
-
/** @ignore */
|
|
10
|
-
export declare type JsonValue = JsonPrimitive | JsonObject | JsonArray;
|
|
4
|
+
declare type JsonArray = JsonValue[];
|
|
5
|
+
declare type JsonPrimitive = string | number | boolean | null;
|
|
6
|
+
declare type JsonValue = JsonPrimitive | JsonObject | JsonArray;
|
|
11
7
|
/**
|
|
12
8
|
* Interface to pass an asymmetric private key and, optionally, its associated JWK Key ID to be
|
|
13
9
|
* added as a `kid` JOSE Header Parameter.
|
|
@@ -89,42 +85,6 @@ export declare type ClientAuthenticationMethod = 'client_secret_basic' | 'client
|
|
|
89
85
|
* ```
|
|
90
86
|
*/
|
|
91
87
|
export declare type JWSAlgorithm = 'PS256' | 'ES256' | 'RS256' | 'EdDSA';
|
|
92
|
-
/**
|
|
93
|
-
* JSON Web Key
|
|
94
|
-
*
|
|
95
|
-
* @ignore
|
|
96
|
-
*/
|
|
97
|
-
export interface JWK {
|
|
98
|
-
/** Key Type */
|
|
99
|
-
readonly kty?: string;
|
|
100
|
-
/** Key ID */
|
|
101
|
-
readonly kid?: string;
|
|
102
|
-
/** Algorithm */
|
|
103
|
-
readonly alg?: string;
|
|
104
|
-
/** Public Key Use */
|
|
105
|
-
readonly use?: string;
|
|
106
|
-
/** Key Operations */
|
|
107
|
-
readonly key_ops?: string[];
|
|
108
|
-
/** (RSA) Exponent */
|
|
109
|
-
readonly e?: string;
|
|
110
|
-
/** (RSA) Modulus */
|
|
111
|
-
readonly n?: string;
|
|
112
|
-
/**
|
|
113
|
-
* (EC) Curve
|
|
114
|
-
*
|
|
115
|
-
* (OKP) The subtype of key pair
|
|
116
|
-
*/
|
|
117
|
-
readonly crv?: string;
|
|
118
|
-
/**
|
|
119
|
-
* (EC) X Coordinate
|
|
120
|
-
*
|
|
121
|
-
* (OKP) The public key
|
|
122
|
-
*/
|
|
123
|
-
readonly x?: string;
|
|
124
|
-
/** (EC) Y Coordinate */
|
|
125
|
-
readonly y?: string;
|
|
126
|
-
readonly [parameter: string]: JsonValue | undefined;
|
|
127
|
-
}
|
|
128
88
|
/**
|
|
129
89
|
* Authorization Server Metadata
|
|
130
90
|
*
|
|
@@ -413,11 +373,11 @@ export interface Client {
|
|
|
413
373
|
token_endpoint_auth_method?: ClientAuthenticationMethod;
|
|
414
374
|
/**
|
|
415
375
|
* JWS `alg` algorithm required for signing the ID Token issued to this Client. When not
|
|
416
|
-
* configured the default is to allow only
|
|
376
|
+
* configured the default is to allow only algorithms listed in
|
|
417
377
|
* {@link AuthorizationServer.id_token_signing_alg_values_supported `as.id_token_signing_alg_values_supported`}
|
|
418
378
|
* and fall back to `RS256` when the authorization server metadata is not set.
|
|
419
379
|
*/
|
|
420
|
-
id_token_signed_response_alg?:
|
|
380
|
+
id_token_signed_response_alg?: string;
|
|
421
381
|
/**
|
|
422
382
|
* JWS `alg` algorithm required for signing authorization responses. When not configured the
|
|
423
383
|
* default is to allow only {@link JWSAlgorithm supported algorithms} listed in
|
|
@@ -432,18 +392,18 @@ export interface Client {
|
|
|
432
392
|
require_auth_time?: boolean;
|
|
433
393
|
/**
|
|
434
394
|
* JWS `alg` algorithm REQUIRED for signing UserInfo Responses. When not configured the default is
|
|
435
|
-
* to allow only
|
|
395
|
+
* to allow only algorithms listed in
|
|
436
396
|
* {@link AuthorizationServer.userinfo_signing_alg_values_supported `as.userinfo_signing_alg_values_supported`}
|
|
437
397
|
* and fall back to `RS256` when the authorization server metadata is not set.
|
|
438
398
|
*/
|
|
439
|
-
userinfo_signed_response_alg?:
|
|
399
|
+
userinfo_signed_response_alg?: string;
|
|
440
400
|
/**
|
|
441
401
|
* JWS `alg` algorithm REQUIRED for signed introspection responses. When not configured the
|
|
442
|
-
* default is to allow only
|
|
402
|
+
* default is to allow only algorithms listed in
|
|
443
403
|
* {@link AuthorizationServer.introspection_signing_alg_values_supported `as.introspection_signing_alg_values_supported`}
|
|
444
404
|
* and fall back to `RS256` when the authorization server metadata is not set.
|
|
445
405
|
*/
|
|
446
|
-
introspection_signed_response_alg?:
|
|
406
|
+
introspection_signed_response_alg?: string;
|
|
447
407
|
/** Default Maximum Authentication Age. */
|
|
448
408
|
default_max_age?: number;
|
|
449
409
|
[metadata: string]: JsonValue | undefined;
|
|
@@ -579,7 +539,7 @@ export declare function issueRequestObject(as: AuthorizationServer, client: Clie
|
|
|
579
539
|
* @param parameters Authorization Request parameters.
|
|
580
540
|
*
|
|
581
541
|
* @see [RFC 9126 - OAuth 2.0 Pushed Authorization Requests](https://www.rfc-editor.org/rfc/rfc9126.html#name-pushed-authorization-reques)
|
|
582
|
-
* @see [draft-ietf-oauth-dpop-
|
|
542
|
+
* @see [draft-ietf-oauth-dpop-11 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-11.html#name-dpop-with-pushed-authorizat)
|
|
583
543
|
*/
|
|
584
544
|
export declare function pushedAuthorizationRequest(as: AuthorizationServer, client: Client, parameters: URLSearchParams, options?: PushedAuthorizationRequestOptions): Promise<Response>;
|
|
585
545
|
export interface PushedAuthorizationResponse {
|
|
@@ -646,7 +606,7 @@ export interface ProtectedResourceRequestOptions extends Omit<HttpRequestOptions
|
|
|
646
606
|
* @param body Request body compatible with the Fetch API and the request's method.
|
|
647
607
|
*
|
|
648
608
|
* @see [RFC 6750 - The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://www.rfc-editor.org/rfc/rfc6750.html#section-2.1)
|
|
649
|
-
* @see [draft-ietf-oauth-dpop-
|
|
609
|
+
* @see [draft-ietf-oauth-dpop-11 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-11.html#name-protected-resource-access)
|
|
650
610
|
*/
|
|
651
611
|
export declare function protectedResourceRequest(accessToken: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | string, url: URL, headers: Headers, body: RequestInit['body'], options?: ProtectedResourceRequestOptions): Promise<Response>;
|
|
652
612
|
export interface UserInfoRequestOptions extends HttpRequestOptions, DPoPRequestOptions {
|
|
@@ -662,7 +622,7 @@ export interface UserInfoRequestOptions extends HttpRequestOptions, DPoPRequestO
|
|
|
662
622
|
* @param accessToken Access Token value.
|
|
663
623
|
*
|
|
664
624
|
* @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo)
|
|
665
|
-
* @see [draft-ietf-oauth-dpop-
|
|
625
|
+
* @see [draft-ietf-oauth-dpop-11 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-11.html#name-protected-resource-access)
|
|
666
626
|
*/
|
|
667
627
|
export declare function userInfoRequest(as: AuthorizationServer, client: Client, accessToken: string, options?: UserInfoRequestOptions): Promise<Response>;
|
|
668
628
|
export interface UserInfoResponse {
|
|
@@ -703,31 +663,6 @@ export interface UserInfoResponse {
|
|
|
703
663
|
* @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse)
|
|
704
664
|
*/
|
|
705
665
|
export declare const skipSubjectCheck: unique symbol;
|
|
706
|
-
export interface SkipJWTSignatureCheckOptions {
|
|
707
|
-
/**
|
|
708
|
-
* DANGER ZONE
|
|
709
|
-
*
|
|
710
|
-
* When JWT assertions are received via direct communication between the Client and the
|
|
711
|
-
* Token/UserInfo/Introspection endpoint (which they are in this library's supported profiles and
|
|
712
|
-
* exposed functions) the TLS server validation MAY be used to validate the issuer in place of
|
|
713
|
-
* checking the assertion's signature.
|
|
714
|
-
*
|
|
715
|
-
* Set this to `true` to omit verifying the JWT assertion's signature (e.g. ID Token, JWT Signed
|
|
716
|
-
* Introspection, or JWT Signed UserInfo Response).
|
|
717
|
-
*
|
|
718
|
-
* Setting this to `true` also means that:
|
|
719
|
-
*
|
|
720
|
-
* - The Authorization Server's JSON Web Key Set will not be requested. That is useful for
|
|
721
|
-
* javascript runtimes that execute on the edge and cannot reliably share an in-memory cache of
|
|
722
|
-
* the JSON Web Key Set in between invocations.
|
|
723
|
-
* - Any JWS Algorithm may be used, not just the {@link JWSAlgorithm supported ones}.
|
|
724
|
-
*
|
|
725
|
-
* Default is `false`.
|
|
726
|
-
*/
|
|
727
|
-
skipJwtSignatureCheck?: boolean;
|
|
728
|
-
}
|
|
729
|
-
export interface ProcessUserInfoResponseOptions extends HttpRequestOptions, SkipJWTSignatureCheckOptions {
|
|
730
|
-
}
|
|
731
666
|
/**
|
|
732
667
|
* Validates Response instance to be one coming from the
|
|
733
668
|
* {@link AuthorizationServer.userinfo_endpoint `as.userinfo_endpoint`}.
|
|
@@ -744,7 +679,7 @@ export interface ProcessUserInfoResponseOptions extends HttpRequestOptions, Skip
|
|
|
744
679
|
* OAuth 2.0 error was returned.
|
|
745
680
|
* @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo)
|
|
746
681
|
*/
|
|
747
|
-
export declare function processUserInfoResponse(as: AuthorizationServer, client: Client, expectedSubject: string | typeof skipSubjectCheck, response: Response
|
|
682
|
+
export declare function processUserInfoResponse(as: AuthorizationServer, client: Client, expectedSubject: string | typeof skipSubjectCheck, response: Response): Promise<UserInfoResponse>;
|
|
748
683
|
export interface TokenEndpointRequestOptions extends HttpRequestOptions, AuthenticatedRequestOptions, DPoPRequestOptions {
|
|
749
684
|
/** Any additional parameters to send. This cannot override existing parameter values. */
|
|
750
685
|
additionalParameters?: URLSearchParams;
|
|
@@ -759,7 +694,7 @@ export interface TokenEndpointRequestOptions extends HttpRequestOptions, Authent
|
|
|
759
694
|
*
|
|
760
695
|
* @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-6)
|
|
761
696
|
* @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens)
|
|
762
|
-
* @see [draft-ietf-oauth-dpop-
|
|
697
|
+
* @see [draft-ietf-oauth-dpop-11 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-11.html#name-dpop-access-token-request)
|
|
763
698
|
*/
|
|
764
699
|
export declare function refreshTokenGrantRequest(as: AuthorizationServer, client: Client, refreshToken: string, options?: TokenEndpointRequestOptions): Promise<Response>;
|
|
765
700
|
/**
|
|
@@ -780,8 +715,6 @@ export declare function getValidatedIdTokenClaims(ref: OpenIDTokenEndpointRespon
|
|
|
780
715
|
* @returns JWT Claims Set from an ID Token, or undefined if there is no ID Token in `ref`.
|
|
781
716
|
*/
|
|
782
717
|
export declare function getValidatedIdTokenClaims(ref: TokenEndpointResponse): IDToken | undefined;
|
|
783
|
-
export interface ProcessRefreshTokenResponseOptions extends HttpRequestOptions, SkipJWTSignatureCheckOptions {
|
|
784
|
-
}
|
|
785
718
|
/**
|
|
786
719
|
* Validates Refresh Token Grant Response instance to be one coming from the
|
|
787
720
|
* {@link AuthorizationServer.token_endpoint `as.token_endpoint`}.
|
|
@@ -796,7 +729,7 @@ export interface ProcessRefreshTokenResponseOptions extends HttpRequestOptions,
|
|
|
796
729
|
* @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-6)
|
|
797
730
|
* @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens)
|
|
798
731
|
*/
|
|
799
|
-
export declare function processRefreshTokenResponse(as: AuthorizationServer, client: Client, response: Response
|
|
732
|
+
export declare function processRefreshTokenResponse(as: AuthorizationServer, client: Client, response: Response): Promise<TokenEndpointResponse | OAuth2Error>;
|
|
800
733
|
/**
|
|
801
734
|
* Performs an Authorization Code grant request at the
|
|
802
735
|
* {@link AuthorizationServer.token_endpoint `as.token_endpoint`}.
|
|
@@ -811,7 +744,7 @@ export declare function processRefreshTokenResponse(as: AuthorizationServer, cli
|
|
|
811
744
|
* @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1)
|
|
812
745
|
* @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth)
|
|
813
746
|
* @see [RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients (PKCE)](https://www.rfc-editor.org/rfc/rfc7636.html#section-4)
|
|
814
|
-
* @see [draft-ietf-oauth-dpop-
|
|
747
|
+
* @see [draft-ietf-oauth-dpop-11 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-11.html#name-dpop-access-token-request)
|
|
815
748
|
*/
|
|
816
749
|
export declare function authorizationCodeGrantRequest(as: AuthorizationServer, client: Client, callbackParameters: CallbackParameters, redirectUri: string, codeVerifier: string, options?: TokenEndpointRequestOptions): Promise<Response>;
|
|
817
750
|
interface JWTPayload {
|
|
@@ -883,8 +816,6 @@ export declare const expectNoNonce: unique symbol;
|
|
|
883
816
|
* indicate no `auth_time` ID Token claim value check should be performed.
|
|
884
817
|
*/
|
|
885
818
|
export declare const skipAuthTimeCheck: unique symbol;
|
|
886
|
-
export interface ProcessAuthorizationCodeOpenIDResponseOptions extends HttpRequestOptions, SkipJWTSignatureCheckOptions {
|
|
887
|
-
}
|
|
888
819
|
/**
|
|
889
820
|
* (OpenID Connect only) Validates Authorization Code Grant Response instance to be one coming from
|
|
890
821
|
* the {@link AuthorizationServer.token_endpoint `as.token_endpoint`}.
|
|
@@ -905,7 +836,7 @@ export interface ProcessAuthorizationCodeOpenIDResponseOptions extends HttpReque
|
|
|
905
836
|
* @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1)
|
|
906
837
|
* @see [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth)
|
|
907
838
|
*/
|
|
908
|
-
export declare function processAuthorizationCodeOpenIDResponse(as: AuthorizationServer, client: Client, response: Response, expectedNonce?: string | typeof expectNoNonce, maxAge?: number | typeof skipAuthTimeCheck
|
|
839
|
+
export declare function processAuthorizationCodeOpenIDResponse(as: AuthorizationServer, client: Client, response: Response, expectedNonce?: string | typeof expectNoNonce, maxAge?: number | typeof skipAuthTimeCheck): Promise<OpenIDTokenEndpointResponse | OAuth2Error>;
|
|
909
840
|
/**
|
|
910
841
|
* (OAuth 2.0 without OpenID Connect only) Validates Authorization Code Grant Response instance to
|
|
911
842
|
* be one coming from the {@link AuthorizationServer.token_endpoint `as.token_endpoint`}.
|
|
@@ -930,7 +861,7 @@ export interface ClientCredentialsGrantRequestOptions extends HttpRequestOptions
|
|
|
930
861
|
* @param client Client Metadata.
|
|
931
862
|
*
|
|
932
863
|
* @see [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.4)
|
|
933
|
-
* @see [draft-ietf-oauth-dpop-
|
|
864
|
+
* @see [draft-ietf-oauth-dpop-11 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-11.html#name-dpop-access-token-request)
|
|
934
865
|
*/
|
|
935
866
|
export declare function clientCredentialsGrantRequest(as: AuthorizationServer, client: Client, parameters: URLSearchParams, options?: ClientCredentialsGrantRequestOptions): Promise<Response>;
|
|
936
867
|
/**
|
|
@@ -1020,8 +951,6 @@ export interface IntrospectionResponse {
|
|
|
1020
951
|
};
|
|
1021
952
|
readonly [claim: string]: JsonValue | undefined;
|
|
1022
953
|
}
|
|
1023
|
-
export interface ProcessIntrospectionResponseOptions extends HttpRequestOptions, SkipJWTSignatureCheckOptions {
|
|
1024
|
-
}
|
|
1025
954
|
/**
|
|
1026
955
|
* Validates Response instance to be one coming from the
|
|
1027
956
|
* {@link AuthorizationServer.introspection_endpoint `as.introspection_endpoint`}.
|
|
@@ -1036,44 +965,7 @@ export interface ProcessIntrospectionResponseOptions extends HttpRequestOptions,
|
|
|
1036
965
|
* @see [RFC 7662 - OAuth 2.0 Token Introspection](https://www.rfc-editor.org/rfc/rfc7662.html#section-2)
|
|
1037
966
|
* @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)
|
|
1038
967
|
*/
|
|
1039
|
-
export declare function processIntrospectionResponse(as: AuthorizationServer, client: Client, response: Response
|
|
1040
|
-
/** @ignore */
|
|
1041
|
-
export interface JwksRequestOptions extends HttpRequestOptions {
|
|
1042
|
-
}
|
|
1043
|
-
/**
|
|
1044
|
-
* Performs a request to the {@link AuthorizationServer.jwks_uri `as.jwks_uri`}.
|
|
1045
|
-
*
|
|
1046
|
-
* @ignore
|
|
1047
|
-
*
|
|
1048
|
-
* @param as Authorization Server Metadata.
|
|
1049
|
-
*
|
|
1050
|
-
* @see [JWK Set Format](https://www.rfc-editor.org/rfc/rfc7517.html#section-5)
|
|
1051
|
-
* @see [RFC 8414 - OAuth 2.0 Authorization Server Metadata](https://www.rfc-editor.org/rfc/rfc8414.html#section-3)
|
|
1052
|
-
* @see [OpenID Connect Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig)
|
|
1053
|
-
*/
|
|
1054
|
-
export declare function jwksRequest(as: AuthorizationServer, options?: JwksRequestOptions): Promise<Response>;
|
|
1055
|
-
/**
|
|
1056
|
-
* JSON Web Key Set
|
|
1057
|
-
*
|
|
1058
|
-
* @ignore
|
|
1059
|
-
*/
|
|
1060
|
-
export interface JsonWebKeySet {
|
|
1061
|
-
/** Array of JWK Values */
|
|
1062
|
-
readonly keys: JWK[];
|
|
1063
|
-
}
|
|
1064
|
-
/**
|
|
1065
|
-
* Validates Response instance to be one coming from the
|
|
1066
|
-
* {@link AuthorizationServer.jwks_uri `as.jwks_uri`}.
|
|
1067
|
-
*
|
|
1068
|
-
* @ignore
|
|
1069
|
-
*
|
|
1070
|
-
* @param response Resolved value from {@link jwksRequest}.
|
|
1071
|
-
*
|
|
1072
|
-
* @returns Resolves with an object representing the parsed successful response.
|
|
1073
|
-
*
|
|
1074
|
-
* @see [JWK Set Format](https://www.rfc-editor.org/rfc/rfc7517.html#section-5)
|
|
1075
|
-
*/
|
|
1076
|
-
export declare function processJwksResponse(response: Response): Promise<JsonWebKeySet>;
|
|
968
|
+
export declare function processIntrospectionResponse(as: AuthorizationServer, client: Client, response: Response): Promise<IntrospectionResponse | OAuth2Error>;
|
|
1077
969
|
/**
|
|
1078
970
|
* Same as {@link validateAuthResponse} but for signed JARM responses.
|
|
1079
971
|
*
|
|
@@ -1168,11 +1060,9 @@ export declare function processDeviceAuthorizationResponse(as: AuthorizationServ
|
|
|
1168
1060
|
* @param deviceCode Device Code.
|
|
1169
1061
|
*
|
|
1170
1062
|
* @see [RFC 8628 - OAuth 2.0 Device Authorization Grant](https://www.rfc-editor.org/rfc/rfc8628.html#section-3.4)
|
|
1171
|
-
* @see [draft-ietf-oauth-dpop-
|
|
1063
|
+
* @see [draft-ietf-oauth-dpop-11 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-11.html#name-dpop-access-token-request)
|
|
1172
1064
|
*/
|
|
1173
1065
|
export declare function deviceCodeGrantRequest(as: AuthorizationServer, client: Client, deviceCode: string, options?: TokenEndpointRequestOptions): Promise<Response>;
|
|
1174
|
-
export interface ProcessDeviceCodeResponseOptions extends HttpRequestOptions, SkipJWTSignatureCheckOptions {
|
|
1175
|
-
}
|
|
1176
1066
|
/**
|
|
1177
1067
|
* Validates Device Authorization Grant Response instance to be one coming from the
|
|
1178
1068
|
* {@link AuthorizationServer.token_endpoint `as.token_endpoint`}.
|
|
@@ -1186,7 +1076,7 @@ export interface ProcessDeviceCodeResponseOptions extends HttpRequestOptions, Sk
|
|
|
1186
1076
|
* OAuth 2.0 error was returned.
|
|
1187
1077
|
* @see [RFC 8628 - OAuth 2.0 Device Authorization Grant](https://www.rfc-editor.org/rfc/rfc8628.html#section-3.4)
|
|
1188
1078
|
*/
|
|
1189
|
-
export declare function processDeviceCodeResponse(as: AuthorizationServer, client: Client, response: Response
|
|
1079
|
+
export declare function processDeviceCodeResponse(as: AuthorizationServer, client: Client, response: Response): Promise<TokenEndpointResponse | OAuth2Error>;
|
|
1190
1080
|
export interface GenerateKeyPairOptions {
|
|
1191
1081
|
/** Indicates whether or not the private key may be exported. Default is `false`. */
|
|
1192
1082
|
extractable?: boolean;
|
|
@@ -1199,14 +1089,4 @@ export interface GenerateKeyPairOptions {
|
|
|
1199
1089
|
* @param alg Supported JWS `alg` Algorithm identifier.
|
|
1200
1090
|
*/
|
|
1201
1091
|
export declare function generateKeyPair(alg: JWSAlgorithm, options?: GenerateKeyPairOptions): Promise<CryptoKeyPair>;
|
|
1202
|
-
/**
|
|
1203
|
-
* Calculates a base64url-encoded SHA-256 JWK Thumbprint.
|
|
1204
|
-
*
|
|
1205
|
-
* @ignore
|
|
1206
|
-
*
|
|
1207
|
-
* @param key A public extractable CryptoKey.
|
|
1208
|
-
*
|
|
1209
|
-
* @see [RFC 7638 - JSON Web Key (JWK) Thumbprint](https://www.rfc-editor.org/rfc/rfc7638.html)
|
|
1210
|
-
*/
|
|
1211
|
-
export declare function calculateJwkThumbprint(key: CryptoKey): Promise<string>;
|
|
1212
1092
|
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 = '
|
|
4
|
+
const VERSION = 'v2.0.1';
|
|
5
5
|
USER_AGENT = `${NAME}/${VERSION}`;
|
|
6
6
|
}
|
|
7
7
|
const encoder = new TextEncoder();
|
|
@@ -432,6 +432,21 @@ export async function issueRequestObject(as, client, parameters, privateKey) {
|
|
|
432
432
|
resource.length > 1) {
|
|
433
433
|
claims.resource = resource;
|
|
434
434
|
}
|
|
435
|
+
if (parameters.has('claims')) {
|
|
436
|
+
const value = parameters.get('claims');
|
|
437
|
+
if (value === '[object Object]') {
|
|
438
|
+
throw new OPE('"claims" parameter must be passed as a UTF-8 encoded JSON');
|
|
439
|
+
}
|
|
440
|
+
try {
|
|
441
|
+
claims.claims = JSON.parse(value);
|
|
442
|
+
}
|
|
443
|
+
catch {
|
|
444
|
+
throw new OPE('failed to parse the "claims" parameter as JSON');
|
|
445
|
+
}
|
|
446
|
+
if (!isJsonObject(claims.claims)) {
|
|
447
|
+
throw new OPE('"claims" parameter must be a top level object');
|
|
448
|
+
}
|
|
449
|
+
}
|
|
435
450
|
return jwt({
|
|
436
451
|
alg: determineJWSAlgorithm(key),
|
|
437
452
|
typ: 'oauth-authz-req+jwt',
|
|
@@ -469,9 +484,14 @@ async function dpopProofJwt(headers, options, url, htm, accessToken) {
|
|
|
469
484
|
}, privateKey);
|
|
470
485
|
headers.set('dpop', proof);
|
|
471
486
|
}
|
|
487
|
+
const jwkCache = Symbol();
|
|
472
488
|
async function publicJwk(key) {
|
|
489
|
+
if (key[jwkCache]) {
|
|
490
|
+
return key[jwkCache];
|
|
491
|
+
}
|
|
473
492
|
const { kty, e, n, x, y, crv } = await crypto.subtle.exportKey('jwk', key);
|
|
474
|
-
|
|
493
|
+
const jwk = (key[jwkCache] = { kty, e, n, x, y, crv });
|
|
494
|
+
return jwk;
|
|
475
495
|
}
|
|
476
496
|
export async function pushedAuthorizationRequest(as, client, parameters, options) {
|
|
477
497
|
assertAs(as);
|
|
@@ -489,9 +509,6 @@ export async function pushedAuthorizationRequest(as, client, parameters, options
|
|
|
489
509
|
headers.set('accept', 'application/json');
|
|
490
510
|
if (options?.DPoP !== undefined) {
|
|
491
511
|
await dpopProofJwt(headers, options.DPoP, url, 'POST');
|
|
492
|
-
if (!body.has('dpop_jkt')) {
|
|
493
|
-
body.set('dpop_jkt', await calculateJwkThumbprint(options.DPoP.publicKey));
|
|
494
|
-
}
|
|
495
512
|
}
|
|
496
513
|
return authenticatedRequest(as, client, 'POST', url, body, headers, options);
|
|
497
514
|
}
|
|
@@ -631,31 +648,30 @@ export async function userInfoRequest(as, client, accessToken, options) {
|
|
|
631
648
|
}
|
|
632
649
|
return protectedResourceRequest(accessToken, 'GET', url, headers, null, options);
|
|
633
650
|
}
|
|
634
|
-
const jwksCache =
|
|
635
|
-
const cryptoKeyCaches = {};
|
|
651
|
+
const jwksCache = Symbol();
|
|
636
652
|
async function getPublicSigKeyFromIssuerJwksUri(as, options, header) {
|
|
637
653
|
const { alg, kid } = header;
|
|
638
654
|
checkSupportedJwsAlg(alg);
|
|
639
655
|
let jwks;
|
|
640
656
|
let age;
|
|
641
|
-
if (jwksCache
|
|
657
|
+
if (as[jwksCache]) {
|
|
642
658
|
;
|
|
643
|
-
({ jwks, age } = jwksCache
|
|
659
|
+
({ jwks, age } = as[jwksCache]);
|
|
644
660
|
if (age >= 300) {
|
|
645
|
-
jwksCache
|
|
661
|
+
as[jwksCache] = undefined;
|
|
646
662
|
return getPublicSigKeyFromIssuerJwksUri(as, options, header);
|
|
647
663
|
}
|
|
648
664
|
}
|
|
649
665
|
else {
|
|
650
666
|
jwks = await jwksRequest(as, options).then(processJwksResponse);
|
|
651
667
|
age = 0;
|
|
652
|
-
jwksCache
|
|
668
|
+
as[jwksCache] = {
|
|
653
669
|
jwks,
|
|
654
670
|
iat: epochTime(),
|
|
655
671
|
get age() {
|
|
656
672
|
return epochTime() - this.iat;
|
|
657
673
|
},
|
|
658
|
-
}
|
|
674
|
+
};
|
|
659
675
|
}
|
|
660
676
|
let kty;
|
|
661
677
|
switch (alg.slice(0, 2)) {
|
|
@@ -698,7 +714,7 @@ async function getPublicSigKeyFromIssuerJwksUri(as, options, header) {
|
|
|
698
714
|
const { 0: jwk, length } = candidates;
|
|
699
715
|
if (!length) {
|
|
700
716
|
if (age >= 60) {
|
|
701
|
-
jwksCache
|
|
717
|
+
as[jwksCache] = undefined;
|
|
702
718
|
return getPublicSigKeyFromIssuerJwksUri(as, options, header);
|
|
703
719
|
}
|
|
704
720
|
throw new OPE('error when selecting a JWT verification key, no applicable keys found');
|
|
@@ -706,14 +722,9 @@ async function getPublicSigKeyFromIssuerJwksUri(as, options, header) {
|
|
|
706
722
|
else if (length !== 1) {
|
|
707
723
|
throw new OPE('error when selecting a JWT verification key, multiple applicable keys found, a "kid" JWT Header Parameter is required');
|
|
708
724
|
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
key = await importJwk({ ...jwk, alg });
|
|
713
|
-
if (key.type !== 'public') {
|
|
714
|
-
throw new OPE('jwks_uri must only contain public keys');
|
|
715
|
-
}
|
|
716
|
-
cryptoKeyCaches[alg].set(jwk, key);
|
|
725
|
+
const key = await importJwk(alg, jwk);
|
|
726
|
+
if (key.type !== 'public') {
|
|
727
|
+
throw new OPE('jwks_uri must only contain public keys');
|
|
717
728
|
}
|
|
718
729
|
return key;
|
|
719
730
|
}
|
|
@@ -721,7 +732,7 @@ export const skipSubjectCheck = Symbol();
|
|
|
721
732
|
function getContentType(response) {
|
|
722
733
|
return response.headers.get('content-type')?.split(';')[0];
|
|
723
734
|
}
|
|
724
|
-
export async function processUserInfoResponse(as, client, expectedSubject, response
|
|
735
|
+
export async function processUserInfoResponse(as, client, expectedSubject, response) {
|
|
725
736
|
assertAs(as);
|
|
726
737
|
assertClient(client);
|
|
727
738
|
if (!(response instanceof Response)) {
|
|
@@ -732,9 +743,7 @@ export async function processUserInfoResponse(as, client, expectedSubject, respo
|
|
|
732
743
|
}
|
|
733
744
|
let json;
|
|
734
745
|
if (getContentType(response) === 'application/jwt') {
|
|
735
|
-
const { claims } = await validateJwt(await preserveBodyStream(response).text(), checkSigningAlgorithm.bind(undefined, client.userinfo_signed_response_alg, as.userinfo_signing_alg_values_supported),
|
|
736
|
-
? getPublicSigKeyFromIssuerJwksUri.bind(undefined, as, options)
|
|
737
|
-
: noSignatureCheck)
|
|
746
|
+
const { claims } = await validateJwt(await preserveBodyStream(response).text(), checkSigningAlgorithm.bind(undefined, client.userinfo_signed_response_alg, as.userinfo_signing_alg_values_supported), noSignatureCheck)
|
|
738
747
|
.then(validateOptionalAudience.bind(undefined, client.client_id))
|
|
739
748
|
.then(validateOptionalIssuer.bind(undefined, as.issuer));
|
|
740
749
|
json = claims;
|
|
@@ -810,7 +819,7 @@ export function getValidatedIdTokenClaims(ref) {
|
|
|
810
819
|
}
|
|
811
820
|
return idTokenClaims.get(ref);
|
|
812
821
|
}
|
|
813
|
-
async function processGenericAccessTokenResponse(as, client, response,
|
|
822
|
+
async function processGenericAccessTokenResponse(as, client, response, ignoreIdToken = false, ignoreRefreshToken = false) {
|
|
814
823
|
assertAs(as);
|
|
815
824
|
assertClient(client);
|
|
816
825
|
if (!(response instanceof Response)) {
|
|
@@ -860,9 +869,7 @@ async function processGenericAccessTokenResponse(as, client, response, options,
|
|
|
860
869
|
throw new OPE('"response" body "id_token" property must be a non-empty string');
|
|
861
870
|
}
|
|
862
871
|
if (json.id_token) {
|
|
863
|
-
const { claims } = await validateJwt(json.id_token, checkSigningAlgorithm.bind(undefined, client.id_token_signed_response_alg, as.id_token_signing_alg_values_supported),
|
|
864
|
-
? getPublicSigKeyFromIssuerJwksUri.bind(undefined, as, options)
|
|
865
|
-
: noSignatureCheck)
|
|
872
|
+
const { claims } = await validateJwt(json.id_token, checkSigningAlgorithm.bind(undefined, client.id_token_signed_response_alg, as.id_token_signing_alg_values_supported), noSignatureCheck)
|
|
866
873
|
.then(validatePresence.bind(undefined, ['aud', 'exp', 'iat', 'iss', 'sub']))
|
|
867
874
|
.then(validateIssuer.bind(undefined, as.issuer))
|
|
868
875
|
.then(validateAudience.bind(undefined, client.client_id));
|
|
@@ -877,8 +884,8 @@ async function processGenericAccessTokenResponse(as, client, response, options,
|
|
|
877
884
|
}
|
|
878
885
|
return json;
|
|
879
886
|
}
|
|
880
|
-
export async function processRefreshTokenResponse(as, client, response
|
|
881
|
-
return processGenericAccessTokenResponse(as, client, response
|
|
887
|
+
export async function processRefreshTokenResponse(as, client, response) {
|
|
888
|
+
return processGenericAccessTokenResponse(as, client, response);
|
|
882
889
|
}
|
|
883
890
|
function validateOptionalAudience(expected, result) {
|
|
884
891
|
if (result.claims.aud !== undefined) {
|
|
@@ -948,8 +955,8 @@ function validatePresence(required, result) {
|
|
|
948
955
|
}
|
|
949
956
|
export const expectNoNonce = Symbol();
|
|
950
957
|
export const skipAuthTimeCheck = Symbol();
|
|
951
|
-
export async function processAuthorizationCodeOpenIDResponse(as, client, response, expectedNonce, maxAge
|
|
952
|
-
const result = await processGenericAccessTokenResponse(as, client, response
|
|
958
|
+
export async function processAuthorizationCodeOpenIDResponse(as, client, response, expectedNonce, maxAge) {
|
|
959
|
+
const result = await processGenericAccessTokenResponse(as, client, response);
|
|
953
960
|
if (isOAuth2Error(result)) {
|
|
954
961
|
return result;
|
|
955
962
|
}
|
|
@@ -993,7 +1000,7 @@ export async function processAuthorizationCodeOpenIDResponse(as, client, respons
|
|
|
993
1000
|
return result;
|
|
994
1001
|
}
|
|
995
1002
|
export async function processAuthorizationCodeOAuth2Response(as, client, response) {
|
|
996
|
-
const result = await processGenericAccessTokenResponse(as, client, response,
|
|
1003
|
+
const result = await processGenericAccessTokenResponse(as, client, response, true);
|
|
997
1004
|
if (isOAuth2Error(result)) {
|
|
998
1005
|
return result;
|
|
999
1006
|
}
|
|
@@ -1017,7 +1024,7 @@ export async function clientCredentialsGrantRequest(as, client, parameters, opti
|
|
|
1017
1024
|
return tokenEndpointRequest(as, client, 'client_credentials', new URLSearchParams(parameters), options);
|
|
1018
1025
|
}
|
|
1019
1026
|
export async function processClientCredentialsResponse(as, client, response) {
|
|
1020
|
-
const result = await processGenericAccessTokenResponse(as, client, response,
|
|
1027
|
+
const result = await processGenericAccessTokenResponse(as, client, response, true, true);
|
|
1021
1028
|
if (isOAuth2Error(result)) {
|
|
1022
1029
|
return result;
|
|
1023
1030
|
}
|
|
@@ -1078,7 +1085,7 @@ export async function introspectionRequest(as, client, token, options) {
|
|
|
1078
1085
|
}
|
|
1079
1086
|
return authenticatedRequest(as, client, 'POST', url, body, headers, options);
|
|
1080
1087
|
}
|
|
1081
|
-
export async function processIntrospectionResponse(as, client, response
|
|
1088
|
+
export async function processIntrospectionResponse(as, client, response) {
|
|
1082
1089
|
assertAs(as);
|
|
1083
1090
|
assertClient(client);
|
|
1084
1091
|
if (!(response instanceof Response)) {
|
|
@@ -1093,9 +1100,7 @@ export async function processIntrospectionResponse(as, client, response, options
|
|
|
1093
1100
|
}
|
|
1094
1101
|
let json;
|
|
1095
1102
|
if (getContentType(response) === 'application/token-introspection+jwt') {
|
|
1096
|
-
const { claims } = await validateJwt(await preserveBodyStream(response).text(), checkSigningAlgorithm.bind(undefined, client.introspection_signed_response_alg, as.introspection_signing_alg_values_supported),
|
|
1097
|
-
? getPublicSigKeyFromIssuerJwksUri.bind(undefined, as, options)
|
|
1098
|
-
: noSignatureCheck)
|
|
1103
|
+
const { claims } = await validateJwt(await preserveBodyStream(response).text(), checkSigningAlgorithm.bind(undefined, client.introspection_signed_response_alg, as.introspection_signing_alg_values_supported), noSignatureCheck)
|
|
1099
1104
|
.then(checkJwtType.bind(undefined, 'token-introspection+jwt'))
|
|
1100
1105
|
.then(validatePresence.bind(undefined, ['aud', 'iat', 'iss']))
|
|
1101
1106
|
.then(validateIssuer.bind(undefined, as.issuer))
|
|
@@ -1121,7 +1126,7 @@ export async function processIntrospectionResponse(as, client, response, options
|
|
|
1121
1126
|
}
|
|
1122
1127
|
return json;
|
|
1123
1128
|
}
|
|
1124
|
-
|
|
1129
|
+
async function jwksRequest(as, options) {
|
|
1125
1130
|
assertAs(as);
|
|
1126
1131
|
if (typeof as.jwks_uri !== 'string') {
|
|
1127
1132
|
throw new TypeError('"as.jwks_uri" must be a string');
|
|
@@ -1137,7 +1142,7 @@ export async function jwksRequest(as, options) {
|
|
|
1137
1142
|
signal: options?.signal ? signal(options.signal) : null,
|
|
1138
1143
|
}).then(processDpopNonce);
|
|
1139
1144
|
}
|
|
1140
|
-
|
|
1145
|
+
async function processJwksResponse(response) {
|
|
1141
1146
|
if (!(response instanceof Response)) {
|
|
1142
1147
|
throw new TypeError('"response" must be an instance of Response');
|
|
1143
1148
|
}
|
|
@@ -1403,8 +1408,8 @@ export function validateAuthResponse(as, client, parameters, expectedState) {
|
|
|
1403
1408
|
}
|
|
1404
1409
|
return new CallbackParameters(parameters);
|
|
1405
1410
|
}
|
|
1406
|
-
async function importJwk(jwk) {
|
|
1407
|
-
const {
|
|
1411
|
+
async function importJwk(alg, jwk) {
|
|
1412
|
+
const { ext, key_ops, use, ...key } = jwk;
|
|
1408
1413
|
let algorithm;
|
|
1409
1414
|
switch (alg) {
|
|
1410
1415
|
case 'PS256':
|
|
@@ -1494,8 +1499,8 @@ export async function deviceCodeGrantRequest(as, client, deviceCode, options) {
|
|
|
1494
1499
|
parameters.set('device_code', deviceCode);
|
|
1495
1500
|
return tokenEndpointRequest(as, client, 'urn:ietf:params:oauth:grant-type:device_code', parameters, options);
|
|
1496
1501
|
}
|
|
1497
|
-
export async function processDeviceCodeResponse(as, client, response
|
|
1498
|
-
return processGenericAccessTokenResponse(as, client, response
|
|
1502
|
+
export async function processDeviceCodeResponse(as, client, response) {
|
|
1503
|
+
return processGenericAccessTokenResponse(as, client, response);
|
|
1499
1504
|
}
|
|
1500
1505
|
export async function generateKeyPair(alg, options) {
|
|
1501
1506
|
let algorithm;
|
|
@@ -1530,25 +1535,3 @@ export async function generateKeyPair(alg, options) {
|
|
|
1530
1535
|
}
|
|
1531
1536
|
return (crypto.subtle.generateKey(algorithm, options?.extractable ?? false, ['sign', 'verify']));
|
|
1532
1537
|
}
|
|
1533
|
-
export async function calculateJwkThumbprint(key) {
|
|
1534
|
-
if (!isPublicKey(key) || !key.extractable) {
|
|
1535
|
-
throw new TypeError('"key" must be an extractable public CryptoKey');
|
|
1536
|
-
}
|
|
1537
|
-
determineJWSAlgorithm(key);
|
|
1538
|
-
const jwk = await crypto.subtle.exportKey('jwk', key);
|
|
1539
|
-
let components;
|
|
1540
|
-
switch (jwk.kty) {
|
|
1541
|
-
case 'EC':
|
|
1542
|
-
components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y };
|
|
1543
|
-
break;
|
|
1544
|
-
case 'OKP':
|
|
1545
|
-
components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x };
|
|
1546
|
-
break;
|
|
1547
|
-
case 'RSA':
|
|
1548
|
-
components = { e: jwk.e, kty: jwk.kty, n: jwk.n };
|
|
1549
|
-
break;
|
|
1550
|
-
default:
|
|
1551
|
-
throw new UnsupportedOperationError();
|
|
1552
|
-
}
|
|
1553
|
-
return b64u(await crypto.subtle.digest({ name: 'SHA-256' }, buf(JSON.stringify(components))));
|
|
1554
|
-
}
|