oauth4webapi 1.4.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -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/src/index.ts'
42
+ import * as oauth2 from 'https://deno.land/x/oauth4webapi/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)
package/build/index.d.ts CHANGED
@@ -1,13 +1,9 @@
1
- /** @ignore */
2
- export declare type JsonObject = {
1
+ declare type JsonObject = {
3
2
  [Key in string]?: JsonValue;
4
3
  };
5
- /** @ignore */
6
- export declare type JsonArray = JsonValue[];
7
- /** @ignore */
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 {@link JWSAlgorithm supported algorithms} listed in
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?: JWSAlgorithm;
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 {@link JWSAlgorithm supported algorithms} listed in
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?: JWSAlgorithm;
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 {@link JWSAlgorithm supported algorithms} listed in
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?: JWSAlgorithm;
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-10 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-10.html#name-dpop-with-pushed-authorizat)
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-10 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-10.html#name-protected-resource-access)
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-10 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-10.html#name-protected-resource-access)
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, options?: ProcessUserInfoResponseOptions): Promise<UserInfoResponse>;
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-10 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-10.html#name-dpop-access-token-request)
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, options?: ProcessRefreshTokenResponseOptions): Promise<TokenEndpointResponse | OAuth2Error>;
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-10 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-10.html#name-dpop-access-token-request)
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, options?: ProcessAuthorizationCodeOpenIDResponseOptions): Promise<OpenIDTokenEndpointResponse | OAuth2Error>;
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-10 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-10.html#name-dpop-access-token-request)
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, options?: ProcessIntrospectionResponseOptions): Promise<IntrospectionResponse | OAuth2Error>;
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
  *
@@ -1084,7 +976,7 @@ export declare function processJwksResponse(response: Response): Promise<JsonWeb
1084
976
  *
1085
977
  * @returns Validated Authorization Response parameters or Authorization Error Response.
1086
978
  *
1087
- * @see [openid-financial-api-jarm-ID1 - JWT Secured Authorization Response Mode for OAuth 2.0 (JARM)](https://openid.net/specs/openid-financial-api-jarm-ID1.html)
979
+ * @see [JWT Secured Authorization Response Mode for OAuth 2.0 (JARM)](https://openid.net/specs/openid-financial-api-jarm.html)
1088
980
  */
1089
981
  export declare function validateJwtAuthResponse(as: AuthorizationServer, client: Client, parameters: URLSearchParams | URL, expectedState?: string | typeof expectNoState | typeof skipStateCheck, options?: HttpRequestOptions): Promise<CallbackParameters | OAuth2Error>;
1090
982
  /**
@@ -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-10 - OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)](https://www.ietf.org/archive/id/draft-ietf-oauth-dpop-10.html#name-dpop-access-token-request)
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, options?: ProcessDeviceCodeResponseOptions): Promise<TokenEndpointResponse | OAuth2Error>;
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 = 'v1.4.0';
4
+ const VERSION = 'v2.0.0';
5
5
  USER_AGENT = `${NAME}/${VERSION}`;
6
6
  }
7
7
  const encoder = new TextEncoder();
@@ -489,9 +489,6 @@ export async function pushedAuthorizationRequest(as, client, parameters, options
489
489
  headers.set('accept', 'application/json');
490
490
  if (options?.DPoP !== undefined) {
491
491
  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
492
  }
496
493
  return authenticatedRequest(as, client, 'POST', url, body, headers, options);
497
494
  }
@@ -631,31 +628,30 @@ export async function userInfoRequest(as, client, accessToken, options) {
631
628
  }
632
629
  return protectedResourceRequest(accessToken, 'GET', url, headers, null, options);
633
630
  }
634
- const jwksCache = new LRU(20);
635
- const cryptoKeyCaches = {};
631
+ const jwksCache = Symbol();
636
632
  async function getPublicSigKeyFromIssuerJwksUri(as, options, header) {
637
633
  const { alg, kid } = header;
638
634
  checkSupportedJwsAlg(alg);
639
635
  let jwks;
640
636
  let age;
641
- if (jwksCache.has(as.jwks_uri)) {
637
+ if (as[jwksCache]) {
642
638
  ;
643
- ({ jwks, age } = jwksCache.get(as.jwks_uri));
639
+ ({ jwks, age } = as[jwksCache]);
644
640
  if (age >= 300) {
645
- jwksCache.delete(as.jwks_uri);
641
+ as[jwksCache] = undefined;
646
642
  return getPublicSigKeyFromIssuerJwksUri(as, options, header);
647
643
  }
648
644
  }
649
645
  else {
650
646
  jwks = await jwksRequest(as, options).then(processJwksResponse);
651
647
  age = 0;
652
- jwksCache.set(as.jwks_uri, {
648
+ as[jwksCache] = {
653
649
  jwks,
654
650
  iat: epochTime(),
655
651
  get age() {
656
652
  return epochTime() - this.iat;
657
653
  },
658
- });
654
+ };
659
655
  }
660
656
  let kty;
661
657
  switch (alg.slice(0, 2)) {
@@ -698,7 +694,7 @@ async function getPublicSigKeyFromIssuerJwksUri(as, options, header) {
698
694
  const { 0: jwk, length } = candidates;
699
695
  if (!length) {
700
696
  if (age >= 60) {
701
- jwksCache.delete(as.jwks_uri);
697
+ as[jwksCache] = undefined;
702
698
  return getPublicSigKeyFromIssuerJwksUri(as, options, header);
703
699
  }
704
700
  throw new OPE('error when selecting a JWT verification key, no applicable keys found');
@@ -706,14 +702,9 @@ async function getPublicSigKeyFromIssuerJwksUri(as, options, header) {
706
702
  else if (length !== 1) {
707
703
  throw new OPE('error when selecting a JWT verification key, multiple applicable keys found, a "kid" JWT Header Parameter is required');
708
704
  }
709
- cryptoKeyCaches[alg] || (cryptoKeyCaches[alg] = new WeakMap());
710
- let key = cryptoKeyCaches[alg].get(jwk);
711
- if (!key) {
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);
705
+ const key = await importJwk(alg, jwk);
706
+ if (key.type !== 'public') {
707
+ throw new OPE('jwks_uri must only contain public keys');
717
708
  }
718
709
  return key;
719
710
  }
@@ -721,7 +712,7 @@ export const skipSubjectCheck = Symbol();
721
712
  function getContentType(response) {
722
713
  return response.headers.get('content-type')?.split(';')[0];
723
714
  }
724
- export async function processUserInfoResponse(as, client, expectedSubject, response, options) {
715
+ export async function processUserInfoResponse(as, client, expectedSubject, response) {
725
716
  assertAs(as);
726
717
  assertClient(client);
727
718
  if (!(response instanceof Response)) {
@@ -732,9 +723,7 @@ export async function processUserInfoResponse(as, client, expectedSubject, respo
732
723
  }
733
724
  let json;
734
725
  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), options?.skipJwtSignatureCheck !== true
736
- ? getPublicSigKeyFromIssuerJwksUri.bind(undefined, as, options)
737
- : noSignatureCheck)
726
+ const { claims } = await validateJwt(await preserveBodyStream(response).text(), checkSigningAlgorithm.bind(undefined, client.userinfo_signed_response_alg, as.userinfo_signing_alg_values_supported), noSignatureCheck)
738
727
  .then(validateOptionalAudience.bind(undefined, client.client_id))
739
728
  .then(validateOptionalIssuer.bind(undefined, as.issuer));
740
729
  json = claims;
@@ -810,7 +799,7 @@ export function getValidatedIdTokenClaims(ref) {
810
799
  }
811
800
  return idTokenClaims.get(ref);
812
801
  }
813
- async function processGenericAccessTokenResponse(as, client, response, options, ignoreIdToken = false, ignoreRefreshToken = false, skipSignatureCheck = false) {
802
+ async function processGenericAccessTokenResponse(as, client, response, ignoreIdToken = false, ignoreRefreshToken = false) {
814
803
  assertAs(as);
815
804
  assertClient(client);
816
805
  if (!(response instanceof Response)) {
@@ -860,9 +849,7 @@ async function processGenericAccessTokenResponse(as, client, response, options,
860
849
  throw new OPE('"response" body "id_token" property must be a non-empty string');
861
850
  }
862
851
  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), skipSignatureCheck !== true
864
- ? getPublicSigKeyFromIssuerJwksUri.bind(undefined, as, options)
865
- : noSignatureCheck)
852
+ 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
853
  .then(validatePresence.bind(undefined, ['aud', 'exp', 'iat', 'iss', 'sub']))
867
854
  .then(validateIssuer.bind(undefined, as.issuer))
868
855
  .then(validateAudience.bind(undefined, client.client_id));
@@ -877,8 +864,8 @@ async function processGenericAccessTokenResponse(as, client, response, options,
877
864
  }
878
865
  return json;
879
866
  }
880
- export async function processRefreshTokenResponse(as, client, response, options) {
881
- return processGenericAccessTokenResponse(as, client, response, options, undefined, undefined, options?.skipJwtSignatureCheck === true);
867
+ export async function processRefreshTokenResponse(as, client, response) {
868
+ return processGenericAccessTokenResponse(as, client, response);
882
869
  }
883
870
  function validateOptionalAudience(expected, result) {
884
871
  if (result.claims.aud !== undefined) {
@@ -948,8 +935,8 @@ function validatePresence(required, result) {
948
935
  }
949
936
  export const expectNoNonce = Symbol();
950
937
  export const skipAuthTimeCheck = Symbol();
951
- export async function processAuthorizationCodeOpenIDResponse(as, client, response, expectedNonce, maxAge, options) {
952
- const result = await processGenericAccessTokenResponse(as, client, response, options, undefined, undefined, options?.skipJwtSignatureCheck === true);
938
+ export async function processAuthorizationCodeOpenIDResponse(as, client, response, expectedNonce, maxAge) {
939
+ const result = await processGenericAccessTokenResponse(as, client, response);
953
940
  if (isOAuth2Error(result)) {
954
941
  return result;
955
942
  }
@@ -993,7 +980,7 @@ export async function processAuthorizationCodeOpenIDResponse(as, client, respons
993
980
  return result;
994
981
  }
995
982
  export async function processAuthorizationCodeOAuth2Response(as, client, response) {
996
- const result = await processGenericAccessTokenResponse(as, client, response, undefined, true);
983
+ const result = await processGenericAccessTokenResponse(as, client, response, true);
997
984
  if (isOAuth2Error(result)) {
998
985
  return result;
999
986
  }
@@ -1017,7 +1004,7 @@ export async function clientCredentialsGrantRequest(as, client, parameters, opti
1017
1004
  return tokenEndpointRequest(as, client, 'client_credentials', new URLSearchParams(parameters), options);
1018
1005
  }
1019
1006
  export async function processClientCredentialsResponse(as, client, response) {
1020
- const result = await processGenericAccessTokenResponse(as, client, response, undefined, true, true);
1007
+ const result = await processGenericAccessTokenResponse(as, client, response, true, true);
1021
1008
  if (isOAuth2Error(result)) {
1022
1009
  return result;
1023
1010
  }
@@ -1078,7 +1065,7 @@ export async function introspectionRequest(as, client, token, options) {
1078
1065
  }
1079
1066
  return authenticatedRequest(as, client, 'POST', url, body, headers, options);
1080
1067
  }
1081
- export async function processIntrospectionResponse(as, client, response, options) {
1068
+ export async function processIntrospectionResponse(as, client, response) {
1082
1069
  assertAs(as);
1083
1070
  assertClient(client);
1084
1071
  if (!(response instanceof Response)) {
@@ -1093,9 +1080,7 @@ export async function processIntrospectionResponse(as, client, response, options
1093
1080
  }
1094
1081
  let json;
1095
1082
  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), options?.skipJwtSignatureCheck !== true
1097
- ? getPublicSigKeyFromIssuerJwksUri.bind(undefined, as, options)
1098
- : noSignatureCheck)
1083
+ const { claims } = await validateJwt(await preserveBodyStream(response).text(), checkSigningAlgorithm.bind(undefined, client.introspection_signed_response_alg, as.introspection_signing_alg_values_supported), noSignatureCheck)
1099
1084
  .then(checkJwtType.bind(undefined, 'token-introspection+jwt'))
1100
1085
  .then(validatePresence.bind(undefined, ['aud', 'iat', 'iss']))
1101
1086
  .then(validateIssuer.bind(undefined, as.issuer))
@@ -1121,7 +1106,7 @@ export async function processIntrospectionResponse(as, client, response, options
1121
1106
  }
1122
1107
  return json;
1123
1108
  }
1124
- export async function jwksRequest(as, options) {
1109
+ async function jwksRequest(as, options) {
1125
1110
  assertAs(as);
1126
1111
  if (typeof as.jwks_uri !== 'string') {
1127
1112
  throw new TypeError('"as.jwks_uri" must be a string');
@@ -1137,7 +1122,7 @@ export async function jwksRequest(as, options) {
1137
1122
  signal: options?.signal ? signal(options.signal) : null,
1138
1123
  }).then(processDpopNonce);
1139
1124
  }
1140
- export async function processJwksResponse(response) {
1125
+ async function processJwksResponse(response) {
1141
1126
  if (!(response instanceof Response)) {
1142
1127
  throw new TypeError('"response" must be an instance of Response');
1143
1128
  }
@@ -1403,8 +1388,8 @@ export function validateAuthResponse(as, client, parameters, expectedState) {
1403
1388
  }
1404
1389
  return new CallbackParameters(parameters);
1405
1390
  }
1406
- async function importJwk(jwk) {
1407
- const { alg, ext, key_ops, use, ...key } = jwk;
1391
+ async function importJwk(alg, jwk) {
1392
+ const { ext, key_ops, use, ...key } = jwk;
1408
1393
  let algorithm;
1409
1394
  switch (alg) {
1410
1395
  case 'PS256':
@@ -1494,8 +1479,8 @@ export async function deviceCodeGrantRequest(as, client, deviceCode, options) {
1494
1479
  parameters.set('device_code', deviceCode);
1495
1480
  return tokenEndpointRequest(as, client, 'urn:ietf:params:oauth:grant-type:device_code', parameters, options);
1496
1481
  }
1497
- export async function processDeviceCodeResponse(as, client, response, options) {
1498
- return processGenericAccessTokenResponse(as, client, response, options, undefined, undefined, options?.skipJwtSignatureCheck === true);
1482
+ export async function processDeviceCodeResponse(as, client, response) {
1483
+ return processGenericAccessTokenResponse(as, client, response);
1499
1484
  }
1500
1485
  export async function generateKeyPair(alg, options) {
1501
1486
  let algorithm;
@@ -1530,25 +1515,3 @@ export async function generateKeyPair(alg, options) {
1530
1515
  }
1531
1516
  return (crypto.subtle.generateKey(algorithm, options?.extractable ?? false, ['sign', 'verify']));
1532
1517
  }
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
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oauth4webapi",
3
- "version": "1.4.0",
3
+ "version": "2.0.0",
4
4
  "description": "OAuth 2 / OpenID Connect for Web Platform API JavaScript runtimes",
5
5
  "keywords": [
6
6
  "auth",
@@ -46,9 +46,9 @@
46
46
  "build/index.d.ts"
47
47
  ],
48
48
  "scripts": {
49
- "_format": "find src test tap examples conformance -type f -name '*.ts' -o -name '*.mjs' | xargs prettier",
49
+ "_format": "find src test tap examples conformance -type f -name '*.ts' -o -name '*.mjs' -name '*.cjs' | xargs prettier",
50
50
  "build": "rm -rf build && tsc && tsc --declaration true --emitDeclarationOnly true --removeComments false && tsc -p test && tsc -p examples && tsc -p conformance && tsc -p tap",
51
- "conformance": "bash -c 'source .node_flags.sh && ava --config conformance/ava.config.mjs'",
51
+ "conformance": "bash -c 'source .node_flags.sh && ava --config conformance/ava.config.ts'",
52
52
  "docs": "patch-package && typedoc",
53
53
  "format": "npm run _format -- --write",
54
54
  "format-check": "npm run _format -- --check",
@@ -66,21 +66,18 @@
66
66
  "@esbuild-kit/esm-loader": "^2.5.0",
67
67
  "@types/node": "^18.11.9",
68
68
  "@types/qunit": "^2.19.3",
69
- "ava": "^5.0.1",
70
- "bowser": "^2.11.0",
71
- "edge-runtime": "^2.0.1",
72
- "jose": "^4.10.4",
69
+ "ava": "^5.1.0",
70
+ "edge-runtime": "^2.0.2",
71
+ "esbuild": "^0.15.14",
72
+ "jose": "^4.11.0",
73
73
  "patch-package": "^6.5.0",
74
74
  "prettier": "^2.7.1",
75
75
  "prettier-plugin-jsdoc": "^0.4.2",
76
76
  "qunit": "^2.19.3",
77
- "testcafe": "^2.0.2",
78
- "testcafe-browser-provider-browserstack": "^1.14.0",
79
77
  "timekeeper": "^2.2.0",
80
78
  "typedoc": "^0.23.20",
81
79
  "typedoc-plugin-markdown": "^3.13.6",
82
80
  "typescript": "^4.8.4",
83
- "undici": "^5.12.0",
84
- "workerd": "^1.20220926.3"
81
+ "undici": "^5.12.0"
85
82
  }
86
83
  }