@hawcx/oauth-client 5.2.0 → 6.2.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +355 -0
  2. package/README.md +247 -0
  3. package/dist/client-assertion.d.ts.map +1 -1
  4. package/dist/client-assertion.js +6 -2
  5. package/dist/client-assertion.js.map +1 -1
  6. package/dist/delegation/exceptions.d.ts +34 -0
  7. package/dist/delegation/exceptions.d.ts.map +1 -1
  8. package/dist/delegation/exceptions.js +39 -1
  9. package/dist/delegation/exceptions.js.map +1 -1
  10. package/dist/delegation/hawcx.d.ts +6 -2
  11. package/dist/delegation/hawcx.d.ts.map +1 -1
  12. package/dist/delegation/hawcx.js.map +1 -1
  13. package/dist/delegation/index.d.ts +2 -1
  14. package/dist/delegation/index.d.ts.map +1 -1
  15. package/dist/delegation/index.js +3 -1
  16. package/dist/delegation/index.js.map +1 -1
  17. package/dist/delegation/transport.d.ts +6 -2
  18. package/dist/delegation/transport.d.ts.map +1 -1
  19. package/dist/delegation/transport.js +9 -2
  20. package/dist/delegation/transport.js.map +1 -1
  21. package/dist/errors.d.ts +11 -1
  22. package/dist/errors.d.ts.map +1 -1
  23. package/dist/errors.js +1 -0
  24. package/dist/errors.js.map +1 -1
  25. package/dist/index.d.ts +6 -2
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +8 -2
  28. package/dist/index.js.map +1 -1
  29. package/dist/internal/url.d.ts +73 -0
  30. package/dist/internal/url.d.ts.map +1 -0
  31. package/dist/internal/url.js +210 -0
  32. package/dist/internal/url.js.map +1 -0
  33. package/dist/management/jwt_transport.d.ts +44 -3
  34. package/dist/management/jwt_transport.d.ts.map +1 -1
  35. package/dist/management/jwt_transport.js +60 -4
  36. package/dist/management/jwt_transport.js.map +1 -1
  37. package/dist/management/response_signature.d.ts +65 -0
  38. package/dist/management/response_signature.d.ts.map +1 -0
  39. package/dist/management/response_signature.js +170 -0
  40. package/dist/management/response_signature.js.map +1 -0
  41. package/dist/oauth.d.ts +89 -1
  42. package/dist/oauth.d.ts.map +1 -1
  43. package/dist/oauth.js +265 -34
  44. package/dist/oauth.js.map +1 -1
  45. package/dist/profile/client.d.ts +99 -0
  46. package/dist/profile/client.d.ts.map +1 -0
  47. package/dist/profile/client.js +209 -0
  48. package/dist/profile/client.js.map +1 -0
  49. package/dist/profile/errors.d.ts +62 -0
  50. package/dist/profile/errors.d.ts.map +1 -0
  51. package/dist/profile/errors.js +90 -0
  52. package/dist/profile/errors.js.map +1 -0
  53. package/dist/profile/http.d.ts +57 -0
  54. package/dist/profile/http.d.ts.map +1 -0
  55. package/dist/profile/http.js +295 -0
  56. package/dist/profile/http.js.map +1 -0
  57. package/dist/profile/tokens.d.ts +50 -0
  58. package/dist/profile/tokens.d.ts.map +1 -0
  59. package/dist/profile/tokens.js +137 -0
  60. package/dist/profile/tokens.js.map +1 -0
  61. package/dist/profile/types.d.ts +99 -0
  62. package/dist/profile/types.d.ts.map +1 -0
  63. package/dist/profile/types.js +7 -0
  64. package/dist/profile/types.js.map +1 -0
  65. package/dist/stepup/client.d.ts +11 -0
  66. package/dist/stepup/client.d.ts.map +1 -1
  67. package/dist/stepup/client.js +6 -1
  68. package/dist/stepup/client.js.map +1 -1
  69. package/package.json +1 -1
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ /**
3
+ * Verification of the management API's `X-Response-Signature` (TOB-HSDK-11).
4
+ *
5
+ * Every successful jwt-mode (Path A) management response from hx_auth carries
6
+ * `X-Response-Signature`: a compact JWS signed with the shared OAuth signing
7
+ * key that the OP publishes at `${issuer}/.well-known/jwks.json` — the same
8
+ * JWKS that verifies ID tokens. Its payload is exactly
9
+ *
10
+ * { "body_sha256": base64url(sha256(<exact response body bytes>)), "iat": <unix s> }
11
+ *
12
+ * Verifying it restores the response authentication the legacy ECIES
13
+ * transport always had (signature + timestamp skew on every response).
14
+ *
15
+ * Checks, all fail-closed:
16
+ * - the header is present and is a compact JWS whose protected header names
17
+ * a `kid`;
18
+ * - `alg` is one of ES256 / ES384 / ES512 (the server's KMS key is an EC key
19
+ * and the alg follows its curve). `none`, HS*, RS*, EdDSA are rejected —
20
+ * this forecloses alg-substitution / key-confusion;
21
+ * - the signature verifies against the issuer JWKS (jose `RemoteJWKSet`:
22
+ * cached, and refetched once when the `kid` is unknown — key rotation);
23
+ * - `iat` is present and within ±clockSkewSeconds of local time;
24
+ * - the payload is a response signature, not some other token minted with
25
+ * the same key (TOB-HSDK-9 type confusion): `body_sha256` is required and
26
+ * `aud`, `sub`, `nonce` must be absent — an ID token always carries
27
+ * `aud`/`sub`;
28
+ * - `body_sha256` equals base64url(sha256(raw body bytes)), compared in
29
+ * constant time. The hash is taken over the raw bytes as received, before
30
+ * any decoding or JSON parsing.
31
+ *
32
+ * Failures are split so callers can react correctly:
33
+ * - {@link ResponseSignatureInvalidError} (`code: 'response_signature_invalid'`)
34
+ * — missing/empty header or a signature that does not verify;
35
+ * - {@link ResponseSignatureUnavailableError}
36
+ * (`code: 'response_signature_unavailable'`) — the signing keys could not
37
+ * be obtained (JWKS fetch failed / timed out / non-200 / malformed, or the
38
+ * kid is unknown while jose's refetch cooldown suppresses a refetch). The
39
+ * request may already have been applied server-side.
40
+ * Both subclass `DelegationResponseError` and carry fixed, non-leaky messages.
41
+ *
42
+ * Not part of the public API (not re-exported from the package index).
43
+ */
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.ResponseSignatureVerifier = exports.RESPONSE_SIGNATURE_HEADER = void 0;
46
+ const node_crypto_1 = require("node:crypto");
47
+ const jose_1 = require("jose");
48
+ const exceptions_1 = require("../delegation/exceptions");
49
+ /** Response-signature header name (HTTP headers are case-insensitive). */
50
+ exports.RESPONSE_SIGNATURE_HEADER = 'X-Response-Signature';
51
+ /** EC algorithms the server's KMS signing key can produce — nothing else. */
52
+ const ALLOWED_ALGS = Object.freeze(['ES256', 'ES384', 'ES512']);
53
+ /**
54
+ * Claims that mark a token as something other than a response signature.
55
+ * Deliberately `aud` is forbidden rather than repurposed: request binding
56
+ * (anti-replay within the iat window) is designed server-side in
57
+ * hawcx/hx_auth#278 as dedicated custom claims (`req_jti` / `htm` / `htu` /
58
+ * `cid`), explicitly NOT `aud` — keep this list as is.
59
+ */
60
+ const FORBIDDEN_CLAIMS = Object.freeze(['aud', 'sub', 'nonce']);
61
+ /** Generic, non-leaky messages; detail (if any) is attached as `cause`. */
62
+ const MSG_MISSING = 'Management API response is missing its signature';
63
+ const MSG_INVALID = 'Management API response signature verification failed';
64
+ const MSG_UNAVAILABLE = 'Management API response signature could not be verified: signing keys unavailable';
65
+ class ResponseSignatureVerifier {
66
+ constructor(options) {
67
+ // jose handles caching (10 min max age), concurrent-fetch coalescing, and a
68
+ // single refetch on an unknown `kid` (rate-limited by its 30s cooldown) —
69
+ // the same machinery HawcxOAuth uses for ID-token verification.
70
+ this.jwks = (0, jose_1.createRemoteJWKSet)(new URL(options.jwksUri), {
71
+ timeoutDuration: options.timeoutMs,
72
+ });
73
+ this.clockSkewSeconds = options.clockSkewSeconds;
74
+ }
75
+ /**
76
+ * Verify `signature` (the header value, or null when absent) over the EXACT
77
+ * response body bytes. Resolves on success; throws
78
+ * {@link ResponseSignatureInvalidError} or
79
+ * {@link ResponseSignatureUnavailableError} otherwise.
80
+ */
81
+ async verify(signature, body) {
82
+ if (!signature) {
83
+ throw new exceptions_1.ResponseSignatureInvalidError(MSG_MISSING);
84
+ }
85
+ // Set by the key resolver when the keys could not be obtained, as opposed
86
+ // to a signature that was checked and found bad.
87
+ let keysUnavailable = false;
88
+ let payloadBytes;
89
+ try {
90
+ const result = await (0, jose_1.compactVerify)(signature, async (protectedHeader, token) => {
91
+ if (typeof protectedHeader.kid !== 'string' || protectedHeader.kid.length === 0) {
92
+ throw new Error('response signature has no kid');
93
+ }
94
+ // If jose may refetch on a miss (not cooling down), a miss means the
95
+ // kid is absent from a freshly fetched JWKS → invalid. If the
96
+ // cooldown suppresses the refetch, the kid may simply be newer than
97
+ // our cache (rotation) → unavailable.
98
+ const canRefetch = !this.jwks.coolingDown;
99
+ try {
100
+ return await this.jwks(protectedHeader, token);
101
+ }
102
+ catch (err) {
103
+ if (err instanceof jose_1.errors.JWKSNoMatchingKey) {
104
+ keysUnavailable = !canRefetch;
105
+ }
106
+ else if (!(err instanceof jose_1.errors.JWKSMultipleMatchingKeys)) {
107
+ // Fetch failure, timeout, non-200, malformed JWKS, network error.
108
+ keysUnavailable = true;
109
+ }
110
+ throw err;
111
+ }
112
+ }, { algorithms: [...ALLOWED_ALGS] });
113
+ payloadBytes = result.payload;
114
+ }
115
+ catch (err) {
116
+ if (keysUnavailable) {
117
+ throw new exceptions_1.ResponseSignatureUnavailableError(MSG_UNAVAILABLE, { cause: err });
118
+ }
119
+ throw new exceptions_1.ResponseSignatureInvalidError(MSG_INVALID, { cause: err });
120
+ }
121
+ let claims;
122
+ try {
123
+ const parsed = JSON.parse(Buffer.from(payloadBytes).toString('utf-8'));
124
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
125
+ throw new Error('payload is not a JSON object');
126
+ }
127
+ claims = parsed;
128
+ }
129
+ catch (err) {
130
+ throw new exceptions_1.ResponseSignatureInvalidError(MSG_INVALID, { cause: err });
131
+ }
132
+ // Type-confusion guard (TOB-HSDK-9): only a response signature qualifies.
133
+ for (const claim of FORBIDDEN_CLAIMS) {
134
+ if (Object.prototype.hasOwnProperty.call(claims, claim)) {
135
+ throw new exceptions_1.ResponseSignatureInvalidError(MSG_INVALID, {
136
+ cause: new Error(`unexpected '${claim}' claim in response signature`),
137
+ });
138
+ }
139
+ }
140
+ const claimedHash = claims['body_sha256'];
141
+ if (typeof claimedHash !== 'string' || claimedHash.length === 0) {
142
+ throw new exceptions_1.ResponseSignatureInvalidError(MSG_INVALID, {
143
+ cause: new Error("response signature has no 'body_sha256' claim"),
144
+ });
145
+ }
146
+ // Freshness: `iat` required, within the configured skew either way.
147
+ const iat = claims['iat'];
148
+ if (typeof iat !== 'number' || !Number.isFinite(iat)) {
149
+ throw new exceptions_1.ResponseSignatureInvalidError(MSG_INVALID, {
150
+ cause: new Error("response signature has no numeric 'iat' claim"),
151
+ });
152
+ }
153
+ const nowSec = Date.now() / 1000;
154
+ if (iat > nowSec + this.clockSkewSeconds || iat < nowSec - this.clockSkewSeconds) {
155
+ throw new exceptions_1.ResponseSignatureInvalidError(MSG_INVALID, {
156
+ cause: new Error(`response signature 'iat' outside allowed skew (${this.clockSkewSeconds}s)`),
157
+ });
158
+ }
159
+ // Body binding: base64url(sha256(raw bytes)), no padding, constant-time.
160
+ const actual = Buffer.from((0, node_crypto_1.createHash)('sha256').update(body).digest('base64url').replace(/=+$/, ''), 'utf-8');
161
+ const claimed = Buffer.from(claimedHash, 'utf-8');
162
+ if (actual.length !== claimed.length || !(0, node_crypto_1.timingSafeEqual)(actual, claimed)) {
163
+ throw new exceptions_1.ResponseSignatureInvalidError(MSG_INVALID, {
164
+ cause: new Error('response body does not match the signed body_sha256'),
165
+ });
166
+ }
167
+ }
168
+ }
169
+ exports.ResponseSignatureVerifier = ResponseSignatureVerifier;
170
+ //# sourceMappingURL=response_signature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response_signature.js","sourceRoot":"","sources":["../../src/management/response_signature.ts"],"names":[],"mappings":"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"}
package/dist/oauth.d.ts CHANGED
@@ -17,6 +17,7 @@
17
17
  */
18
18
  import { type JWTPayload } from 'jose';
19
19
  import { ClientAssertionSigner } from './client-assertion';
20
+ import { ProfileClient, type ProfileClientOptions } from './profile/client';
20
21
  export interface HawcxOAuthConfig {
21
22
  /** Your Hawcx config-id (sent as the `X-Config-Id` header on token exchange) */
22
23
  configId: string;
@@ -66,6 +67,46 @@ export interface HawcxOAuthIssuerConfig {
66
67
  * Spec.md §3.3.
67
68
  */
68
69
  clockToleranceSeconds?: number;
70
+ /**
71
+ * Optional custom domain (a DNS CNAME to Hawcx), e.g.
72
+ * `https://auth.example.com`. `scheme://host[:port]` only: https (http only
73
+ * for loopback), ASCII/punycode host or IP literal, no userinfo, path,
74
+ * query or fragment; one trailing `/` allowed. Canonicalised (lower-cased,
75
+ * default port dropped). `null`/`undefined` = unset. Invalid →
76
+ * `HawcxOAuthError` `invalid_custom_domain`, before any discovery fetch.
77
+ *
78
+ * Affects only the browser-facing URLs from {@link HawcxOAuth.buildAuthorizeUrl}
79
+ * and {@link HawcxOAuth.buildEndSessionUrl} (scheme + host + port swapped,
80
+ * path kept). Discovery, token exchange, JWKS and the `iss` check stay on
81
+ * the issuer.
82
+ */
83
+ customDomain?: string | null;
84
+ }
85
+ /** Options for {@link HawcxOAuth.buildAuthorizeUrl}. */
86
+ export interface AuthorizeUrlOptions {
87
+ /** `redirect_uri` registered for the client. Required. */
88
+ redirectUri: string;
89
+ /** Opaque CSRF `state`. Required. */
90
+ state: string;
91
+ /** PKCE S256 `code_challenge`. Required. */
92
+ codeChallenge: string;
93
+ /** Optional OIDC `nonce`; pass the same value to `exchangeCode` as `expectedNonce`. */
94
+ nonce?: string;
95
+ /** Space-separated scopes (default `openid`). */
96
+ scope?: string;
97
+ /** Optional OIDC `prompt` (e.g. `login`). */
98
+ prompt?: string;
99
+ /**
100
+ * Additional query parameters (non-empty keys, string values). May not
101
+ * override any parameter the SDK sets, nor `request` / `request_uri`.
102
+ */
103
+ extraParams?: Record<string, string>;
104
+ }
105
+ /** Options for {@link HawcxOAuth.buildEndSessionUrl}. */
106
+ export interface EndSessionUrlOptions {
107
+ postLogoutRedirectUri?: string;
108
+ idTokenHint?: string;
109
+ state?: string;
69
110
  }
70
111
  export interface JwtClaims extends JWTPayload {
71
112
  /** Subject (user ID) */
@@ -168,6 +209,8 @@ export declare class HawcxOAuth {
168
209
  * which returns a *new* configured client (this field is `readonly`).
169
210
  */
170
211
  private readonly clientAssertionSigner;
212
+ /** Validated custom-domain origin for browser URLs; `null` if unset or legacy mode. */
213
+ private readonly customDomain;
171
214
  /**
172
215
  * Construct a legacy-mode client. For discovery mode, prefer
173
216
  * {@link HawcxOAuth.fromIssuer}.
@@ -212,6 +255,14 @@ export declare class HawcxOAuth {
212
255
  * (the assertion would be silently ignored).
213
256
  */
214
257
  withClientAssertion(signer: ClientAssertionSigner): HawcxOAuth;
258
+ /**
259
+ * Client for the Hawcx profile service, built from this discovery-mode
260
+ * client and its {@link withClientAssertion} signer. Same as
261
+ * `new ProfileClient(oauth, options)`.
262
+ *
263
+ * @throws {HawcxError} in legacy mode or without a client-assertion signer.
264
+ */
265
+ profile(options?: ProfileClientOptions): ProfileClient;
215
266
  /**
216
267
  * Exchange authorization code for id_token and verified claims.
217
268
  *
@@ -257,9 +308,46 @@ export declare class HawcxOAuth {
257
308
  refreshJwks(): void;
258
309
  /**
259
310
  * @deprecated since 5.1.0 — renamed to {@link refreshJwks} for cross-SDK
260
- * consistency. Will be removed in 6.0.0. Behaviour is identical.
311
+ * consistency. Will be removed in a future major version. Behaviour is identical.
261
312
  */
262
313
  clearCache(): void;
263
314
  private clearCacheWarned;
315
+ /**
316
+ * Build the browser `/authorize` URL (discovery mode only; no I/O).
317
+ *
318
+ * Base is the discovered `authorization_endpoint`; with `customDomain` set,
319
+ * its scheme + host + port are replaced by the custom domain's (path and any
320
+ * existing query kept). Sets `response_type=code`, `client_id`,
321
+ * `redirect_uri`, `scope` (default `openid`), `state`, `code_challenge`,
322
+ * `code_challenge_method=S256`, plus `nonce` / `prompt` / `extraParams`
323
+ * when given.
324
+ *
325
+ * @throws {HawcxOAuthError} `issuer_mode_required` in legacy mode;
326
+ * `invalid_request` for a missing required option or a reserved
327
+ * `extraParams` key.
328
+ * @throws {DiscoveryError} `invalid_discovery_document` if the discovered
329
+ * `authorization_endpoint` is missing or insecure.
330
+ */
331
+ buildAuthorizeUrl(options: AuthorizeUrlOptions): string;
332
+ /**
333
+ * Build the browser RP-initiated logout URL (discovery mode only; no I/O).
334
+ * Base is the discovered `end_session_endpoint`, with the same
335
+ * `customDomain` origin swap as {@link buildAuthorizeUrl}. Always sets
336
+ * `client_id`; `post_logout_redirect_uri`, `id_token_hint` and `state` when given.
337
+ *
338
+ * @throws {HawcxOAuthError} `issuer_mode_required` in legacy mode.
339
+ * @throws {DiscoveryError} `invalid_discovery_document` if the discovered
340
+ * `end_session_endpoint` is missing or insecure.
341
+ */
342
+ buildEndSessionUrl(options?: EndSessionUrlOptions | null): string;
343
+ /**
344
+ * Build a browser URL from a discovered endpoint, validated lazily (so
345
+ * fromIssuer keeps accepting documents without it): origin (custom domain
346
+ * if set, else the endpoint's) + RAW path + RAW query + `&` + SDK params.
347
+ * The endpoint query is copied verbatim, never re-serialised, and may not
348
+ * carry any of `sdkNames`; an `extraKeys` name it already carries is an
349
+ * `invalid_request` (RFC 6749 §3.1: no repeated parameters).
350
+ */
351
+ private browserUrl;
264
352
  }
265
353
  //# sourceMappingURL=oauth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}