@hawcx/oauth-client 4.0.1 → 5.1.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/dist/errors.js CHANGED
@@ -3,27 +3,71 @@
3
3
  * Hawcx OAuth Errors
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.TokenVerificationError = exports.TokenExchangeError = exports.HawcxOAuthError = void 0;
7
- class HawcxOAuthError extends Error {
6
+ exports.DiscoveryError = exports.TokenVerificationError = exports.TokenExchangeError = exports.HawcxOAuthError = exports.HawcxError = void 0;
7
+ /**
8
+ * Canonical root for every Hawcx SDK error, aligned with the Java/Python SDKs
9
+ * (`HawcxError`). Catch this to handle any SDK-originated failure.
10
+ */
11
+ class HawcxError extends Error {
8
12
  constructor(message) {
13
+ super(message);
14
+ this.name = 'HawcxError';
15
+ }
16
+ }
17
+ exports.HawcxError = HawcxError;
18
+ /**
19
+ * Historical base, retained for back-compat. Now a subclass of {@link HawcxError};
20
+ * every SDK error is catchable via either. New code can catch `HawcxError`.
21
+ *
22
+ * Carries optional structured {@link HawcxOAuthErrorFields} (`error` /
23
+ * `errorDescription`) so callers can dispatch on a stable code without parsing
24
+ * `.message`. These are populated at the relevant raise sites and never alter
25
+ * the thrown message string.
26
+ */
27
+ class HawcxOAuthError extends HawcxError {
28
+ constructor(message, fields) {
9
29
  super(message);
10
30
  this.name = 'HawcxOAuthError';
31
+ if (fields?.error !== undefined)
32
+ this.error = fields.error;
33
+ if (fields?.errorDescription !== undefined)
34
+ this.errorDescription = fields.errorDescription;
11
35
  }
12
36
  }
13
37
  exports.HawcxOAuthError = HawcxOAuthError;
14
38
  class TokenExchangeError extends HawcxOAuthError {
15
- constructor(message, statusCode) {
16
- super(message);
39
+ constructor(message, statusCode, fields) {
40
+ super(message, fields);
17
41
  this.name = 'TokenExchangeError';
18
42
  this.statusCode = statusCode;
19
43
  }
20
44
  }
21
45
  exports.TokenExchangeError = TokenExchangeError;
22
46
  class TokenVerificationError extends HawcxOAuthError {
23
- constructor(message) {
24
- super(message);
47
+ constructor(message, fields) {
48
+ super(message, fields);
25
49
  this.name = 'TokenVerificationError';
26
50
  }
27
51
  }
28
52
  exports.TokenVerificationError = TokenVerificationError;
53
+ /**
54
+ * Thrown when OIDC discovery (`HawcxOAuth.fromIssuer`) cannot resolve a usable
55
+ * provider configuration — DNS / TLS / network failure, non-2xx response from
56
+ * `/.well-known/openid-configuration`, malformed JSON, or a discovery document
57
+ * missing required fields (`token_endpoint`, `jwks_uri`,
58
+ * `id_token_signing_alg_values_supported`).
59
+ *
60
+ * The original failure (when present) is attached as `cause`, so the full
61
+ * diagnostic stack survives.
62
+ */
63
+ class DiscoveryError extends HawcxOAuthError {
64
+ constructor(message, options) {
65
+ super(message, options);
66
+ this.name = 'DiscoveryError';
67
+ if (options?.cause !== undefined) {
68
+ this.cause = options.cause;
69
+ }
70
+ }
71
+ }
72
+ exports.DiscoveryError = DiscoveryError;
29
73
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,MAAa,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AALD,0CAKC;AAED,MAAa,kBAAmB,SAAQ,eAAe;IAGrD,YAAY,OAAe,EAAE,UAAmB;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AARD,gDAQC;AAED,MAAa,sBAAuB,SAAQ,eAAe;IACzD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AALD,wDAKC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAgBH;;;GAGG;AACH,MAAa,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF;AALD,gCAKC;AAED;;;;;;;;GAQG;AACH,MAAa,eAAgB,SAAQ,UAAU;IAM7C,YAAY,OAAe,EAAE,MAA8B;QACzD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,MAAM,EAAE,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3D,IAAI,MAAM,EAAE,gBAAgB,KAAK,SAAS;YAAE,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;IAC9F,CAAC;CACF;AAZD,0CAYC;AAED,MAAa,kBAAmB,SAAQ,eAAe;IAGrD,YAAY,OAAe,EAAE,UAAmB,EAAE,MAA8B;QAC9E,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AARD,gDAQC;AAED,MAAa,sBAAuB,SAAQ,eAAe;IACzD,YAAY,OAAe,EAAE,MAA8B;QACzD,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AALD,wDAKC;AAED;;;;;;;;;GASG;AACH,MAAa,cAAe,SAAQ,eAAe;IACjD,YAAY,OAAe,EAAE,OAAqD;QAChF,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YAChC,IAA4B,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACtD,CAAC;IACH,CAAC;CACF;AARD,wCAQC"}
package/dist/index.d.ts CHANGED
@@ -13,9 +13,11 @@
13
13
  * ```
14
14
  */
15
15
  export { HawcxOAuth } from './oauth';
16
- export type { HawcxOAuthConfig, ExchangeResult, JwtClaims } from './oauth';
17
- export { HawcxOAuthError, TokenExchangeError, TokenVerificationError } from './errors';
16
+ export type { HawcxOAuthConfig, HawcxOAuthIssuerConfig, ExchangeResult, JwtClaims, DiscoveryMetadata, VerifyTokenOptions, } from './oauth';
17
+ export { HawcxError, HawcxOAuthError, TokenExchangeError, TokenVerificationError, DiscoveryError, } from './errors';
18
+ export type { HawcxOAuthErrorFields } from './errors';
19
+ export { ClientAssertionSigner, CLIENT_ASSERTION_TYPE } from './client-assertion';
18
20
  export * from './delegation';
19
21
  export * from './stepup';
20
- export declare const VERSION = "4.0.1";
22
+ export declare const VERSION = "5.1.0";
21
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAGvF,cAAc,cAAc,CAAC;AAG7B,cAAc,UAAU,CAAC;AAEzB,eAAO,MAAM,OAAO,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,YAAY,EACV,gBAAgB,EAChB,sBAAsB,EACtB,cAAc,EACd,SAAS,EACT,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,cAAc,GACf,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEtD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAGlF,cAAc,cAAc,CAAC;AAG7B,cAAc,UAAU,CAAC;AAEzB,eAAO,MAAM,OAAO,UAAU,CAAC"}
package/dist/index.js CHANGED
@@ -28,16 +28,21 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
28
28
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
29
29
  };
30
30
  Object.defineProperty(exports, "__esModule", { value: true });
31
- exports.VERSION = exports.TokenVerificationError = exports.TokenExchangeError = exports.HawcxOAuthError = exports.HawcxOAuth = void 0;
31
+ exports.VERSION = exports.CLIENT_ASSERTION_TYPE = exports.ClientAssertionSigner = exports.DiscoveryError = exports.TokenVerificationError = exports.TokenExchangeError = exports.HawcxOAuthError = exports.HawcxError = exports.HawcxOAuth = void 0;
32
32
  var oauth_1 = require("./oauth");
33
33
  Object.defineProperty(exports, "HawcxOAuth", { enumerable: true, get: function () { return oauth_1.HawcxOAuth; } });
34
34
  var errors_1 = require("./errors");
35
+ Object.defineProperty(exports, "HawcxError", { enumerable: true, get: function () { return errors_1.HawcxError; } });
35
36
  Object.defineProperty(exports, "HawcxOAuthError", { enumerable: true, get: function () { return errors_1.HawcxOAuthError; } });
36
37
  Object.defineProperty(exports, "TokenExchangeError", { enumerable: true, get: function () { return errors_1.TokenExchangeError; } });
37
38
  Object.defineProperty(exports, "TokenVerificationError", { enumerable: true, get: function () { return errors_1.TokenVerificationError; } });
39
+ Object.defineProperty(exports, "DiscoveryError", { enumerable: true, get: function () { return errors_1.DiscoveryError; } });
40
+ var client_assertion_1 = require("./client-assertion");
41
+ Object.defineProperty(exports, "ClientAssertionSigner", { enumerable: true, get: function () { return client_assertion_1.ClientAssertionSigner; } });
42
+ Object.defineProperty(exports, "CLIENT_ASSERTION_TYPE", { enumerable: true, get: function () { return client_assertion_1.CLIENT_ASSERTION_TYPE; } });
38
43
  // Delegation module
39
44
  __exportStar(require("./delegation"), exports);
40
45
  // Step-up module
41
46
  __exportStar(require("./stepup"), exports);
42
- exports.VERSION = '4.0.1';
47
+ exports.VERSION = '5.1.0';
43
48
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;;;;;;;;;;;;;;;AAEH,iCAAqC;AAA5B,mGAAA,UAAU,OAAA;AAEnB,mCAAuF;AAA9E,yGAAA,eAAe,OAAA;AAAE,4GAAA,kBAAkB,OAAA;AAAE,gHAAA,sBAAsB,OAAA;AAEpE,oBAAoB;AACpB,+CAA6B;AAE7B,iBAAiB;AACjB,2CAAyB;AAEZ,QAAA,OAAO,GAAG,OAAO,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;;;;;;;;;;;;;;;AAEH,iCAAqC;AAA5B,mGAAA,UAAU,OAAA;AASnB,mCAMkB;AALhB,oGAAA,UAAU,OAAA;AACV,yGAAA,eAAe,OAAA;AACf,4GAAA,kBAAkB,OAAA;AAClB,gHAAA,sBAAsB,OAAA;AACtB,wGAAA,cAAc,OAAA;AAIhB,uDAAkF;AAAzE,yHAAA,qBAAqB,OAAA;AAAE,yHAAA,qBAAqB,OAAA;AAErD,oBAAoB;AACpB,+CAA6B;AAE7B,iBAAiB;AACjB,2CAAyB;AAEZ,QAAA,OAAO,GAAG,OAAO,CAAC"}
package/dist/oauth.d.ts CHANGED
@@ -1,16 +1,71 @@
1
1
  /**
2
2
  * Hawcx OAuth Client
3
3
  *
4
- * Simple, clean implementation using the jose library for JWT verification.
4
+ * Two construction paths:
5
+ *
6
+ * 1. OIDC discovery (recommended) — `HawcxOAuth.fromIssuer(...)` fetches
7
+ * `<issuer>/.well-known/openid-configuration` once at startup and wires
8
+ * up a verifier that enforces signature + iss + aud + exp + nbf on every
9
+ * subsequent `verifyToken` call.
10
+ *
11
+ * 2. Legacy — `new HawcxOAuth({ configId, baseUrl })` hits the fixed
12
+ * endpoints `/oauth2/token` and `/keys` directly. Backward-compatible
13
+ * with v4.x callers, but does NOT verify `iss` or `aud` — the JWT's
14
+ * signature is the only check.
15
+ *
16
+ * Both modes are safe to share across requests.
5
17
  */
6
18
  import { type JWTPayload } from 'jose';
19
+ import { ClientAssertionSigner } from './client-assertion';
7
20
  export interface HawcxOAuthConfig {
8
- /** Your Hawcx API key (X-Config-Id) */
21
+ /** Your Hawcx config-id (sent as the `X-Config-Id` header on token exchange) */
9
22
  configId: string;
10
23
  /** Base URL override (default: https://api.hawcx.com) */
11
24
  baseUrl?: string;
12
25
  /** Request timeout in ms (default: 10000) */
13
26
  timeout?: number;
27
+ /**
28
+ * Tolerated clock skew in seconds when verifying `exp` and `nbf` claims.
29
+ * Default 10. Set to 0 to require exact-time validation; raise above 10
30
+ * if you regularly see NTP drift between the issuer and this host.
31
+ * Spec.md §3.3.
32
+ */
33
+ clockToleranceSeconds?: number;
34
+ }
35
+ /**
36
+ * Options for the discovery-mode factory.
37
+ *
38
+ * **configId vs clientId.** Hawcx separates the tenant routing key from the
39
+ * audience claim — the SDK forwards each to the right place:
40
+ *
41
+ * - `configId` — opaque per-tenant routing key. Sent verbatim as the
42
+ * `X-Config-Id` header on the token-exchange POST so the OAuth server can
43
+ * look up the tenant.
44
+ * - `clientId` — whatever value the tenant has configured (in the Hawcx admin
45
+ * console) as the `aud` claim on issued id_tokens. The verifier checks the
46
+ * token's `aud` against this exact string.
47
+ *
48
+ * Passing the same value for both fails verification with an audience-mismatch
49
+ * error unless the tenant has configured them identically.
50
+ */
51
+ export interface HawcxOAuthIssuerConfig {
52
+ /** Hawcx issuer URL (e.g. `https://api.hawcx.com`). Used for OIDC discovery and as the expected `iss` claim. */
53
+ issuer: string;
54
+ /** Hawcx tenant config-id; sent as the `X-Config-Id` header on token exchange. */
55
+ configId: string;
56
+ /** Hawcx project / tenant client-id; matched as the expected `aud` claim on id_tokens. */
57
+ clientId: string;
58
+ /** Per-request timeout in ms for token exchange and JWKS fetch (default: 10000) */
59
+ timeout?: number;
60
+ /** Timeout in ms for the one-shot discovery fetch (default: 5000) */
61
+ discoveryTimeout?: number;
62
+ /**
63
+ * Tolerated clock skew in seconds when verifying `exp` and `nbf` claims.
64
+ * Default 10. Set to 0 to require exact-time validation; raise above 10
65
+ * if you regularly see NTP drift between the issuer and this host.
66
+ * Spec.md §3.3.
67
+ */
68
+ clockToleranceSeconds?: number;
14
69
  }
15
70
  export interface JwtClaims extends JWTPayload {
16
71
  /** Subject (user ID) */
@@ -44,55 +99,167 @@ export interface ExchangeResult {
44
99
  /** Verified JWT claims */
45
100
  claims: JwtClaims;
46
101
  }
102
+ /**
103
+ * Subset of the OIDC discovery document the SDK actually consumes.
104
+ * The raw response may include additional fields; they're preserved on
105
+ * `HawcxOAuth.discoveryMetadata` but the SDK only relies on these.
106
+ */
107
+ export interface DiscoveryMetadata {
108
+ issuer: string;
109
+ token_endpoint: string;
110
+ jwks_uri: string;
111
+ id_token_signing_alg_values_supported: string[];
112
+ [key: string]: unknown;
113
+ }
114
+ export interface VerifyTokenOptions {
115
+ /**
116
+ * If set, the JWT's `nonce` claim must equal this value. Use when your
117
+ * authorization request bound a nonce. Checked in both discovery and
118
+ * legacy modes — legacy mode skips `iss` / `aud` but the explicit nonce
119
+ * comparison applies unconditionally when this option is provided.
120
+ */
121
+ nonce?: string;
122
+ }
47
123
  /**
48
124
  * Hawcx OAuth Client
49
125
  *
50
- * Handles code exchange and JWT verification using the jose library.
126
+ * Discovery-mode usage (recommended):
51
127
  *
52
- * @example
53
128
  * ```typescript
54
- * const oauth = new HawcxOAuth({ configId: 'your-api-key' });
55
- *
56
- * // Exchange authorization code for tokens
129
+ * const oauth = await HawcxOAuth.fromIssuer({
130
+ * issuer: 'https://api.hawcx.com',
131
+ * configId: process.env.HAWCX_CONFIG_ID!,
132
+ * clientId: process.env.HAWCX_CLIENT_ID!,
133
+ * });
57
134
  * const { idToken, claims } = await oauth.exchangeCode(code, codeVerifier);
58
- * console.log(claims.sub); // user ID
135
+ * ```
136
+ *
137
+ * Legacy usage (no discovery; aud/iss are not checked):
59
138
  *
60
- * // Later, verify an existing token
61
- * const claims = await oauth.verifyToken(idToken);
139
+ * ```typescript
140
+ * const oauth = new HawcxOAuth({ configId: process.env.HAWCX_CONFIG_ID! });
141
+ * const { idToken, claims } = await oauth.exchangeCode(code, codeVerifier);
62
142
  * ```
63
143
  */
64
144
  export declare class HawcxOAuth {
65
145
  private readonly configId;
66
- private readonly baseUrl;
146
+ private readonly tokenEndpoint;
147
+ private readonly jwksUrl;
67
148
  private readonly timeout;
149
+ private readonly clockToleranceSeconds;
150
+ /** Expected `aud` claim. `null` in legacy mode (audience is not checked). */
151
+ private readonly expectedAudience;
152
+ /** Expected `iss` claim. `null` in legacy mode (issuer is not checked). */
153
+ private readonly expectedIssuer;
154
+ /**
155
+ * id_token signing algorithms accepted by `verifyToken`. In discovery mode
156
+ * this is the intersection of the issuer's advertised algs with the SDK's
157
+ * closed allowlist ({@link DEFAULT_ID_TOKEN_ALGS}). `null` in legacy mode
158
+ * (we have no discovery doc to constrain against, so jose's default
159
+ * "accept whatever the JWKS provides" remains — same as 4.x).
160
+ */
161
+ private readonly allowedAlgorithms;
162
+ /** Resolved OIDC discovery document. `null` in legacy mode. */
163
+ readonly discoveryMetadata: DiscoveryMetadata | null;
68
164
  private jwks;
165
+ /**
166
+ * Optional `private_key_jwt` signer (discovery mode only). `null` ⇒ the
167
+ * token exchange stays public-client + PKCE. Set via {@link withClientAssertion},
168
+ * which returns a *new* configured client (this field is `readonly`).
169
+ */
170
+ private readonly clientAssertionSigner;
171
+ /**
172
+ * Construct a legacy-mode client. For discovery mode, prefer
173
+ * {@link HawcxOAuth.fromIssuer}.
174
+ */
69
175
  constructor(config: HawcxOAuthConfig);
176
+ /**
177
+ * Construct a client via OIDC discovery.
178
+ *
179
+ * Fetches `<issuer>/.well-known/openid-configuration`, reads the token
180
+ * endpoint, JWKS URI, and supported id_token signing algorithm, and wires
181
+ * a verifier that enforces signature + `iss` + `aud` + `exp` + `nbf` on
182
+ * subsequent {@link verifyToken} calls.
183
+ *
184
+ * **Discovery is bounded** at `discoveryTimeout` ms (default 5000) so an
185
+ * unreachable issuer fails fast with {@link DiscoveryError} rather than
186
+ * hanging your bootstrap.
187
+ *
188
+ * @throws {DiscoveryError} if discovery fails to resolve or the document
189
+ * is missing required fields (`token_endpoint`, `jwks_uri`,
190
+ * `id_token_signing_alg_values_supported`).
191
+ */
192
+ static fromIssuer(config: HawcxOAuthIssuerConfig): Promise<HawcxOAuth>;
193
+ /**
194
+ * Opt into `private_key_jwt` client authentication (discovery mode only).
195
+ * When set, the token exchange signs and attaches an RFC 7523
196
+ * `client_assertion` (in addition to PKCE). Without it, the exchange stays
197
+ * public-client + PKCE.
198
+ *
199
+ * Intended to be called once right after {@link fromIssuer}, before the
200
+ * client is shared. Returns `this` for chaining.
201
+ */
202
+ /**
203
+ * @beta Experimental `private_key_jwt` surface; may change before stable.
204
+ *
205
+ * Returns a **new** discovery-mode client configured with the signer (sharing
206
+ * this client's resolved discovery state); the original is unchanged, so a
207
+ * configured client is immutable. Chained usage
208
+ * (`(await fromIssuer(...)).withClientAssertion(...)`) is unaffected.
209
+ *
210
+ * Refuses if the OP's discovery doc advertises
211
+ * `token_endpoint_auth_methods_supported` without `private_key_jwt`
212
+ * (the assertion would be silently ignored).
213
+ */
214
+ withClientAssertion(signer: ClientAssertionSigner): HawcxOAuth;
70
215
  /**
71
216
  * Exchange authorization code for id_token and verified claims.
72
217
  *
73
218
  * @param code - Authorization code from auth flow
74
219
  * @param codeVerifier - PKCE code verifier
75
- * @returns id_token and verified claims
220
+ * @param redirectUri - Optional. If your original authorization request
221
+ * registered a `redirect_uri`, RFC 6749 §4.1.3 requires the token
222
+ * request to carry the same value. Omit if the auth request also omitted it.
223
+ * @param expectedNonce - Optional. If your authorization request bound a
224
+ * `nonce`, pass it here so the returned id_token's `nonce` is verified.
225
+ * Required whenever the token carries a nonce (verification refuses
226
+ * otherwise — OIDC Core §3.1.3.7).
76
227
  */
77
- exchangeCode(code: string, codeVerifier: string): Promise<ExchangeResult>;
228
+ exchangeCode(code: string, codeVerifier: string, redirectUri?: string, expectedNonce?: string): Promise<ExchangeResult>;
78
229
  /**
79
230
  * Verify a JWT token and return its claims.
80
231
  *
81
- * Uses the jose library which handles all signature formats automatically,
82
- * including ECDSA signature conversion between P1363 and DER formats.
232
+ * In **discovery mode**, enforces signature + `iss` + `aud` + `exp` + `nbf`
233
+ * (and the optional `nonce` claim if `options.nonce` is provided).
83
234
  *
84
- * @param token - JWT token to verify
85
- * @returns Verified claims
235
+ * In **legacy mode**, only the signature is verified. Audience and issuer
236
+ * claims are not checked, matching the pre-5.x behavior.
86
237
  */
87
- verifyToken(token: string): Promise<JwtClaims>;
238
+ verifyToken(token: string, options?: VerifyTokenOptions): Promise<JwtClaims>;
88
239
  /**
89
- * Get or create the remote JWKS.
90
- * The jose library handles caching internally.
240
+ * Get or create the remote JWKS. jose handles caching + concurrent-fetch
241
+ * coalescing internally.
242
+ *
243
+ * No single-flight guard is needed here: this method is fully synchronous
244
+ * (no `await` between the null-check and the assignment), so within Node's
245
+ * single-threaded event loop the first caller assigns `this.jwks` before any
246
+ * other code runs. Two concurrent `verifyToken` calls therefore cannot create
247
+ * duplicate `RemoteJWKSet` instances.
91
248
  */
92
249
  private getJwks;
93
250
  /**
94
- * Clear the JWKS cache (useful for testing or key rotation).
251
+ * Drop the cached JWKS so the next `verifyToken` re-fetches it. Useful after
252
+ * an operator-triggered signing-key rotation, or in tests.
253
+ *
254
+ * Canonical name, aligned with the Java (`refreshJwks`) and Python
255
+ * (`refresh_jwks`) SDKs.
256
+ */
257
+ refreshJwks(): void;
258
+ /**
259
+ * @deprecated since 5.1.0 — renamed to {@link refreshJwks} for cross-SDK
260
+ * consistency. Will be removed in 6.0.0. Behaviour is identical.
95
261
  */
96
262
  clearCache(): void;
263
+ private clearCacheWarned;
97
264
  }
98
265
  //# sourceMappingURL=oauth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAiC,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAKtE,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe;IACf,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,sBAAsB;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,MAAM,EAAE,SAAS,CAAC;CACnB;AAQD;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,IAAI,CAAsD;gBAEtD,MAAM,EAAE,gBAAgB;IASpC;;;;;;OAMG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkD/E;;;;;;;;OAQG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IA+BpD;;;OAGG;IACH,OAAO,CAAC,OAAO;IAaf;;OAEG;IACH,UAAU,IAAI,IAAI;CAGnB"}
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}