@hawcx/oauth-client 5.1.0 → 5.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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,253 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [5.2.0] - 2026-06-26
9
+
10
+ ### Added — Management API authentication via `private_key_jwt` (Path A)
11
+
12
+ - **`StepUpClient.withPrivateKeyJwt(...)`** — authenticate `/v1/management/*`
13
+ (step-up, MFA enforcement, phone-number changes) with a per-request EdDSA
14
+ Bearer JWT: `iss` = `sub` = `clientId`, `aud` = the full endpoint URL, ~60s
15
+ `exp`, random `jti`, and a `body_sha256` claim binding the JWT to the exact
16
+ request body bytes. Reuses the same Ed25519 OIDC `private_key_jwt` signing key
17
+ already registered in the admin console — one key, standards-based (RFC 7523),
18
+ no ECIES credential blob required. Tenant routing uses the `X-Config-Id`
19
+ header. Options include `timeoutSeconds` (default 15) and `jwtTtlSeconds`
20
+ (default 60).
21
+ - **`JwtBearerTransport`** — the transport backing the Path A client. Responses
22
+ carry an `X-Response-Signature` (ES256) which callers **may** verify against
23
+ the OIDC JWKS they already trust (optional, customer-side per the Path A spec).
24
+
25
+ ### Changed
26
+
27
+ - The ECIES factories **`StepUpClient.fromSecretKey(...)` / `fromKeys(...)`**
28
+ (the proprietary `hwx_sk_v1_…` blob) are now **deprecated** — they emit a
29
+ one-time `DeprecationWarning` but remain fully functional and will only be
30
+ removed in a future major version.
31
+
32
+ ### Migration (ECIES → `private_key_jwt`)
33
+
34
+ Existing ECIES integrations keep working unchanged; adopting `private_key_jwt`
35
+ is opt-in (spec §10.3):
36
+
37
+ 1. Register your Ed25519 `private_key_jwt` public key in the Admin Console
38
+ (OAuth tab → **Client authentication**) — the same key used for OIDC login.
39
+ 2. Switch the project's Management API auth to **Migrating** (accepts both
40
+ `ecies` and `jwt`) so existing and new callers coexist during rollout.
41
+ 3. Replace `StepUpClient.fromSecretKey(...)` / `fromKeys(...)` with
42
+ `StepUpClient.withPrivateKeyJwt({ baseUrl, configId, clientId, oidcSigningKey, kid })`.
43
+ 4. Once every caller uses `private_key_jwt`, move the project to **Signed
44
+ tokens** (`jwt` only). ECIES EOL date: TBA (removed no earlier than the next
45
+ major version).
46
+
47
+ ### Hardening
48
+
49
+ - `JwtBearerTransport` now bounds every request with a timeout (`timeoutSeconds`,
50
+ default 15) via an `AbortController`, so a connected-but-silent server can no
51
+ longer hang the call or exhaust connection pools. Mirrors the ECIES
52
+ `DelegationTransport`.
53
+ - The HTTP status is now checked **before** parsing the response body, so a
54
+ non-JSON error body (e.g. a WAF/proxy HTML 403) surfaces its HTTP status as a
55
+ `DelegationRequestError` instead of being masked as a JSON parse failure.
56
+
57
+ ## [5.1.0] - 2026-06-13
58
+
59
+ > The `private_key_jwt` / `ClientAssertionSigner` surface is **experimental** (`@beta`)
60
+ > and may change before it is marked stable.
61
+
62
+ ### Cross-SDK consistency
63
+
64
+ - Added `HawcxError` as the canonical root exception (aligns with Java/Python);
65
+ `HawcxOAuthError` now extends it (back-compat — catch either).
66
+ - Added a shared **golden test vector** (`tests/fixtures/golden-assertion.json`,
67
+ byte-identical across the three SDKs) pinning the assertion header/claims/signature
68
+ for a fixed key.
69
+ - Added `refreshJwks()` as the canonical JWKS-cache reset (aligns with the Java
70
+ `refreshJwks()` / Python `refresh_jwks()` SDKs). `clearCache()` is now
71
+ **deprecated** (passthrough; one-time `console.warn`) and will be removed in 6.0.0.
72
+
73
+ ### Production-readiness hardening
74
+
75
+ - `ClientAssertionSigner` no longer memoizes a *rejected* key import — a transient/
76
+ structural import failure no longer permanently poisons the signer.
77
+ - `jti` now sourced from `node:crypto` `randomUUID` (explicit import; was the
78
+ `globalThis.crypto` global).
79
+ - `withClientAssertion` refuses to attach a signer when the OP's discovery doc
80
+ advertises `token_endpoint_auth_methods_supported` without `private_key_jwt`
81
+ (prevents a silent downgrade to public-client).
82
+ - `withClientAssertion` is now **immutable** — returns a *new* configured client
83
+ (the backing `clientAssertionSigner` field is `readonly`) rather than mutating
84
+ in place. Chained usage (`(await fromIssuer(...)).withClientAssertion(...)`) is
85
+ unaffected; callers relying on in-place mutation of the original must use the
86
+ return value.
87
+ - `ClientAssertionSigner` gains `ed25519FromPem(pkcs8Pem, kid)` and
88
+ `ed25519(keyObject, kid)` factories (parity with the Java SDK).
89
+ - Replaced the `expectedAudience ?? ''` dead-code fallback with a non-null assertion.
90
+
91
+ ### Added
92
+
93
+ - **`private_key_jwt` client authentication** (RFC 7523 / OIDC Core §9). New
94
+ `ClientAssertionSigner.ed25519FromJwk(...)` + `HawcxOAuth.withClientAssertion(signer)`
95
+ (discovery mode). When set, `exchangeCode` signs and attaches a `client_assertion`
96
+ (EdDSA/Ed25519 only) alongside PKCE; `aud` is the discovered `token_endpoint`.
97
+ Without a signer, the request is unchanged (public-client + PKCE).
98
+ - `exchangeCode` gains an optional 4th `expectedNonce` argument, threaded to verification.
99
+
100
+ ### Changed / hardened
101
+
102
+ - **https required** on the issuer, `token_endpoint`, and `jwks_uri` (loopback http
103
+ still allowed for local dev/tests) — an http issuer let an on-path attacker swap
104
+ the discovery document.
105
+ - **Nonce**: verification now refuses an id_token that carries a `nonce` when none
106
+ was supplied to verify against (OIDC Core §3.1.3.7), instead of silently skipping it.
107
+ - **`exp` and `iat` required** in discovery mode — a token with no `exp` (never-expiring)
108
+ or no `iat` (no issuance anchor) is rejected.
109
+ - **Structured error fields** on the `HawcxOAuthError` hierarchy: new
110
+ `HawcxOAuthErrorFields` carrying optional `error` / `errorDescription`. The
111
+ token-endpoint error path now populates these from the OAuth `error` /
112
+ `error_description` body so callers can dispatch on a stable code without parsing
113
+ the message string (the message string composition is unchanged for back-compat).
114
+ - JWKS fetch timeout pinned explicitly; token-exchange error bodies that aren't JSON
115
+ are preserved in the error message; negative `clockToleranceSeconds` rejected.
116
+
117
+ ## [5.0.0] - 2026-05-23
118
+
119
+ OIDC discovery support. The legacy `new HawcxOAuth({ configId, baseUrl })`
120
+ constructor is unchanged at the signature level — but verification gains a
121
+ default 10-second clock-tolerance window (see `clockToleranceSeconds`
122
+ below). Apps that depend on strict zero-skew validation should pass
123
+ `clockToleranceSeconds: 0`.
124
+
125
+ ### Added
126
+
127
+ #### OIDC discovery construction path
128
+
129
+ - `HawcxOAuth.fromIssuer({ issuer, configId, clientId })` — static async
130
+ factory that fetches `<issuer>/.well-known/openid-configuration` once at
131
+ startup (5s default timeout) and wires a verifier that enforces signature
132
+ + `iss` + `aud` + `exp` + `nbf` on every subsequent `verifyToken` call.
133
+ The legacy path verifies the signature only.
134
+
135
+ **`configId` vs `clientId`.** Hawcx separates the tenant routing key from
136
+ the audience claim, and the SDK forwards each to the right place:
137
+ - `configId` — sent as `X-Config-Id` on the token-exchange POST (opaque
138
+ tenant routing key)
139
+ - `clientId` — the value the tenant has configured (in the Hawcx admin
140
+ console) as the `aud` claim on issued id_tokens. The verifier matches
141
+ the token's `aud` against this exact string.
142
+
143
+ Passing the same value for both fails verification with
144
+ `Unexpected JWT audience` unless the tenant happens to configure them
145
+ identically.
146
+
147
+ - `HawcxOAuth.prototype.exchangeCode(code, codeVerifier, redirectUri?)` —
148
+ new optional third argument. If your authorization request registered a
149
+ `redirect_uri`, RFC 6749 §4.1.3 requires the token request to carry the
150
+ same value. Omit for flows that didn't include it.
151
+
152
+ - `HawcxOAuth.prototype.verifyToken(token, { nonce })` — new options object
153
+ with optional `nonce` field for callers who bind a nonce to the
154
+ authorization request. Has no effect in legacy mode.
155
+
156
+ - `HawcxOAuth.prototype.discoveryMetadata` — the resolved OIDC discovery
157
+ document. `null` on legacy clients; useful for diagnostics ("which
158
+ token endpoint did we resolve to?", "what signing algorithms?").
159
+
160
+ - `clockToleranceSeconds` option on both `HawcxOAuthConfig` (legacy) and
161
+ `HawcxOAuthIssuerConfig` (discovery) — tolerated clock skew in seconds
162
+ when verifying `exp` and `nbf`. Spec.md §3.3 mandates this knob with a
163
+ recommended default of 10 seconds, which the SDK now applies. Without
164
+ it, jose's default of 0 rejected tokens minted under normal NTP drift
165
+ between issuer and verifier — the root cause of the
166
+ `exchangeCodeTolerant` workaround in `hawcx_admin_console` pre-5.0.
167
+ Pass `clockToleranceSeconds: 0` to opt back into strict exact-time
168
+ validation; raise above 10 if drift on your hosts is wider than that.
169
+
170
+ - **Algorithm allowlist (spec.md §3.3) — discovery mode.** `fromIssuer`
171
+ now intersects the issuer's advertised
172
+ `id_token_signing_alg_values_supported` with a closed SDK allowlist
173
+ (`{RS256, ES256, ES384, ES512, EdDSA}`). If no advertised alg is in
174
+ the allowlist, `DiscoveryError` is thrown at construction time. The
175
+ intersection is then passed to `jose.jwtVerify`'s `algorithms` option
176
+ on every `verifyToken` call, so verify-time enforcement matches what
177
+ was resolved at construction — forecloses key-confusion /
178
+ alg-substitution where the JWKS happens to serve a key type matching
179
+ whatever the JWT header claims. Mirrors the Java SDK
180
+ (`JwtVerifier.DEFAULT_ALGORITHMS`). Legacy mode behavior is unchanged
181
+ (no closed allowlist, no `algorithms:` constraint — same as 4.x).
182
+
183
+ - `DiscoveryError` — new error class for discovery-resolution failures
184
+ (DNS / TLS / network failure, non-2xx response, malformed JSON, missing
185
+ required fields). Underlying cause is preserved as `err.cause`.
186
+
187
+ - New exported types: `HawcxOAuthIssuerConfig`, `DiscoveryMetadata`,
188
+ `VerifyTokenOptions`.
189
+
190
+ ### Changed
191
+
192
+ - `TokenVerificationError.message` now distinguishes audience / issuer
193
+ mismatches from generic signature failures by parsing jose's
194
+ `ERR_JWT_CLAIM_VALIDATION_FAILED` code. Code that pattern-matched on
195
+ the legacy "Invalid signature" message still sees it for signature
196
+ failures; new "Unexpected JWT audience" / "Unexpected JWT issuer"
197
+ messages are now used when those specific claims fail.
198
+
199
+ - `exchangeCode` now sets `grant_type=authorization_code` on the form body.
200
+ 4.x callers won't notice — the OAuth server already inferred the grant
201
+ type from the presence of `code`. Listed here for completeness.
202
+
203
+ ### Notes for upgraders
204
+
205
+ If you only construct via `new HawcxOAuth({ configId })`, nothing changes —
206
+ the legacy path is signature-only verification, same as 4.x. If you want
207
+ proper `aud`/`iss` enforcement, switch to `await HawcxOAuth.fromIssuer(...)`
208
+ and pass both `configId` and `clientId` from the admin console.
209
+
210
+ ## [0.2.0] - 2024-11-20
211
+
212
+ ### Breaking Changes
213
+ - **BREAKING**: `apiKey` parameter is now required in `exchangeCodeForClaims()` and `exchangeCodeForTokenAndClaims()`
214
+ - **BREAKING**: At least one of `publicKey` or `jwksUrl` must be provided for JWT verification
215
+
216
+ ### Added
217
+ - Validation to ensure `apiKey` is provided and non-empty
218
+ - Validation to ensure at least one of `publicKey` or `jwksUrl` is provided
219
+ - Clear error messages for missing required parameters
220
+ - Priority logic: `jwksUrl` takes precedence over `publicKey` when both are provided
221
+
222
+ ### Changed
223
+ - Updated all documentation and examples to use `jwksUrl` as the primary recommended method
224
+ - Updated demo application to include `apiKey` parameter
225
+ - Improved error messages for parameter validation
226
+
227
+ ### Fixed
228
+ - Ensures API key is always sent with OAuth token exchange requests
229
+ - Prevents authentication failures due to missing API key
230
+
231
+ ## [0.1.0] - 2024-01-XX
232
+
233
+ ### Added
234
+ - Initial release of Node.js/TypeScript OAuth client SDK
235
+ - OAuth authorization code exchange with PKCE support
236
+ - JWT verification with RS256, ES256/384/512, and EdDSA algorithms
237
+ - Comprehensive error handling with custom exception classes
238
+ - Hawcx delegation client for MFA setup and management
239
+ - ECIES (X25519 + AES-GCM) encryption for secure backend-to-backend communication
240
+ - Ed25519 and RSA-PSS signing support
241
+ - Full TypeScript type definitions
242
+ - Comprehensive documentation and examples
243
+ - Feature parity with Python SDK
244
+
245
+ ### Features
246
+ - 🔐 Secure JWT verification with configurable validation
247
+ - 🆕 Native PKCE (RFC 7636) support
248
+ - 🚀 Simple, async/await API
249
+ - 🎯 High-level Hawcx client with automatic encryption/signing
250
+ - 🛡️ Comprehensive error handling
251
+ - 📝 Full TypeScript support
252
+ - 🔧 Framework-agnostic (works with Express, Fastify, etc.)
253
+
package/README.md CHANGED
@@ -450,22 +450,35 @@ try {
450
450
 
451
451
  For step-up authentication flows (e.g., changing MFA method requires re-authentication).
452
452
 
453
- ### `StepUpClient`
453
+ ### `StepUpClient` (recommended: `withPrivateKeyJwt`)
454
+
455
+ `StepUpClient.withPrivateKeyJwt` is the recommended construction path. It reuses
456
+ the same Ed25519 `private_key_jwt` signing key already registered in the Hawcx admin
457
+ console for OIDC — one standards-based key, no separate credential blob required.
454
458
 
455
459
  ```typescript
456
460
  import { StepUpClient } from '@hawcx/oauth-client';
457
461
 
458
- const stepUp = StepUpClient.fromSecretKey({
462
+ const privateJwk = JSON.parse(process.env.HAWCX_PRIVATE_JWK!); // OKP/Ed25519, with kid
463
+
464
+ const stepUp = StepUpClient.withPrivateKeyJwt({
459
465
  baseUrl: 'https://api.hawcx.com',
460
- secretKey: process.env.HAWCX_SECRET_KEY!,
461
- relyingParty: 'your-app.com', // Required
462
- apiKey: 'optional-api-key', // Optional
463
- apiPrefix: '/v1', // Optional (default: '/v1')
464
- timeoutSeconds: 15, // Optional
465
- clockSkewSeconds: 300, // Optional
466
+ configId: process.env.HAWCX_CONFIG_ID!, // X-Config-Id tenant routing
467
+ clientId: process.env.HAWCX_CLIENT_ID!, // iss/sub in per-request JWT
468
+ oidcSigningKey: privateJwk, // same key as ClientAssertionSigner
469
+ kid: privateJwk.kid,
470
+ relyingParty: 'your-app.com', // Optional
471
+ apiKey: 'optional-api-key', // Optional
472
+ apiPrefix: '/v1', // Optional (default: '/v1')
466
473
  });
467
474
  ```
468
475
 
476
+ The signing key must be Ed25519 (`kty: 'OKP', crv: 'Ed25519'`). It accepts a JWK
477
+ object, a PKCS#8 PEM string, or a pre-imported jose `KeyLike`.
478
+
479
+ Each request is signed with a short-lived per-request EdDSA JWT whose `aud` is the
480
+ full request URL and whose `body_sha256` claim covers the exact bytes sent.
481
+
469
482
  ### Methods
470
483
 
471
484
  #### `stepUp.startToken(options): Promise<StepUpStartTokenResponse>`
@@ -512,6 +525,23 @@ interface StepUpConsumeResponse {
512
525
  }
513
526
  ```
514
527
 
528
+ ### Legacy (deprecated): `fromSecretKey`
529
+
530
+ `StepUpClient.fromSecretKey` and `StepUpClient.fromKeys` are deprecated since 5.2.0
531
+ and will be removed in a future major version. They use a proprietary ECIES credential
532
+ format. Migrate to `withPrivateKeyJwt`.
533
+
534
+ ```typescript
535
+ // DEPRECATED — migrate to withPrivateKeyJwt above
536
+ import { StepUpClient } from '@hawcx/oauth-client';
537
+
538
+ const stepUp = StepUpClient.fromSecretKey({
539
+ baseUrl: 'https://api.hawcx.com',
540
+ secretKey: process.env.HAWCX_SECRET_KEY!, // hwx_sk_v1_… blob
541
+ relyingParty: 'your-app.com',
542
+ });
543
+ ```
544
+
515
545
  ---
516
546
 
517
547
  ## Examples
@@ -595,9 +625,14 @@ async function revokeAllDevices(userId: string) {
595
625
  ```typescript
596
626
  import { StepUpClient, DelegationClient, MfaMethod } from '@hawcx/oauth-client';
597
627
 
598
- const stepUp = StepUpClient.fromSecretKey({
628
+ const privateJwk = JSON.parse(process.env.HAWCX_PRIVATE_JWK!);
629
+
630
+ const stepUp = StepUpClient.withPrivateKeyJwt({
599
631
  baseUrl: process.env.HAWCX_API_URL!,
600
- secretKey: process.env.HAWCX_SECRET_KEY!,
632
+ configId: process.env.HAWCX_CONFIG_ID!,
633
+ clientId: process.env.HAWCX_CLIENT_ID!,
634
+ oidcSigningKey: privateJwk,
635
+ kid: privateJwk.kid,
601
636
  relyingParty: 'myapp.com',
602
637
  });
603
638
 
package/dist/index.d.ts CHANGED
@@ -19,5 +19,5 @@ export type { HawcxOAuthErrorFields } from './errors';
19
19
  export { ClientAssertionSigner, CLIENT_ASSERTION_TYPE } from './client-assertion';
20
20
  export * from './delegation';
21
21
  export * from './stepup';
22
- export declare const VERSION = "5.1.0";
22
+ export declare const VERSION = "5.2.0";
23
23
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -44,5 +44,5 @@ Object.defineProperty(exports, "CLIENT_ASSERTION_TYPE", { enumerable: true, get:
44
44
  __exportStar(require("./delegation"), exports);
45
45
  // Step-up module
46
46
  __exportStar(require("./stepup"), exports);
47
- exports.VERSION = '5.1.0';
47
+ exports.VERSION = '5.2.0';
48
48
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,109 @@
1
+ /**
2
+ * JWT-bearer transport for the Hawcx management API (Path A: private_key_jwt).
3
+ *
4
+ * Each request is authenticated with a per-request EdDSA JWT whose `aud` is
5
+ * the full request URL, carrying a `body_sha256` claim over the EXACT bytes
6
+ * sent. This mirrors the wire contract verified end-to-end against hx_auth
7
+ * (see spec.md §management-api-auth / Python SDK Path A implementation).
8
+ *
9
+ * Construction:
10
+ * const transport = new JwtBearerTransport({
11
+ * baseUrl: 'https://api.hawcx.com',
12
+ * configId: 'your-config-id',
13
+ * clientId: 'your-client-id',
14
+ * oidcSigningKey: pkcs8Pem, // Ed25519 PKCS#8 PEM — same key registered in admin console
15
+ * kid: 'key-id',
16
+ * });
17
+ *
18
+ * The `http` constructor option accepts an injectable fetch-compatible function
19
+ * (same signature as the global `fetch`) for testing.
20
+ */
21
+ import { type JWK } from 'jose';
22
+ import type { KeyLike } from 'jose';
23
+ import type { JsonObject } from '../delegation/transport';
24
+ /**
25
+ * A fetch-compatible callable — accepts `(url: string, init: RequestInit)`
26
+ * and returns a `Promise<Response>`. Mirrors the global `fetch` signature so
27
+ * the real `fetch` can be passed unchanged.
28
+ */
29
+ export type HttpFetch = (url: string, init: RequestInit) => Promise<Response>;
30
+ export interface JwtBearerTransportOptions {
31
+ /** Base URL of the management API, e.g. `https://api.hawcx.com` */
32
+ baseUrl: string;
33
+ /** Tenant config identifier; forwarded as `X-Config-Id`. */
34
+ configId: string;
35
+ /**
36
+ * Ed25519 private signing key. Accepts:
37
+ * - PKCS#8 PEM string (e.g. `"-----BEGIN PRIVATE KEY-----\n…"`)
38
+ * - JWK object `{ kty:'OKP', crv:'Ed25519', d, x, kid? }`
39
+ * - jose `KeyLike` / `CryptoKey` already imported
40
+ */
41
+ oidcSigningKey: string | JWK | KeyLike;
42
+ /** Key ID embedded in the JWT `kid` header. */
43
+ kid: string;
44
+ /** OAuth client ID; used as both `iss` and `sub` in the per-request JWT. */
45
+ clientId: string;
46
+ /**
47
+ * JWT time-to-live in seconds (default: 60). The server rejects tokens
48
+ * older than its configured TTL; do not set this above 120.
49
+ */
50
+ jwtTtlSeconds?: number;
51
+ /**
52
+ * Per-request timeout in seconds (default: 15). A stalled
53
+ * (connected-but-silent) server would otherwise hang the call forever and
54
+ * can exhaust connection pools server-side. Mirrors the ECIES
55
+ * `DelegationTransport`'s 15s `AbortController`.
56
+ */
57
+ timeoutSeconds?: number;
58
+ /**
59
+ * Injectable fetch implementation. Defaults to the global `fetch`
60
+ * (Node >= 18). Pass a capturing fake in tests.
61
+ */
62
+ http?: HttpFetch;
63
+ }
64
+ /**
65
+ * Drop-in transport for the management API that authenticates via a per-request
66
+ * EdDSA JWT (`private_key_jwt`, Path A).
67
+ *
68
+ * The `send` method has the same name and signature as `DelegationTransport.send`
69
+ * so the factory can swap transports behind `StepUpClient` without any change to
70
+ * the business-method layer.
71
+ */
72
+ export declare class JwtBearerTransport {
73
+ private readonly baseUrl;
74
+ private readonly configId;
75
+ private readonly kid;
76
+ private readonly clientId;
77
+ private readonly jwtTtlSeconds;
78
+ private readonly timeoutMs;
79
+ private readonly http;
80
+ /** Lazily-imported (and memoised) signing key. */
81
+ private keyPromise?;
82
+ private readonly importKeyFn;
83
+ constructor(options: JwtBearerTransportOptions);
84
+ private importKey;
85
+ /**
86
+ * Mint a per-request EdDSA JWT.
87
+ *
88
+ * @param audience - full request URL (`baseUrl + endpoint`), pinned per-call
89
+ * @param bodySha256 - base64url (no-padding) of SHA-256 over the exact body bytes
90
+ */
91
+ private mintJwt;
92
+ /**
93
+ * Send an authenticated POST to `endpoint` with `payload` serialised as JSON.
94
+ *
95
+ * Matches the signature of `DelegationTransport.send` so the two transports
96
+ * are drop-in substitutes behind `StepUpClient`.
97
+ *
98
+ * @param options.endpoint - API path, e.g. `/v1/management/stepup/start-token`
99
+ * @param options.payload - request body; serialised once and hashed; the
100
+ * EXACT same bytes are sent and hashed — no double-serialisation.
101
+ * @param options.headers - optional extra headers merged last (win over built-ins)
102
+ */
103
+ send<TReq extends JsonObject, TRes extends JsonObject>(options: {
104
+ endpoint: string;
105
+ payload: TReq;
106
+ headers?: Record<string, string>;
107
+ }): Promise<TRes>;
108
+ }
109
+ //# sourceMappingURL=jwt_transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt_transport.d.ts","sourceRoot":"","sources":["../../src/management/jwt_transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,EAAmC,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAK1D;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE9E,MAAM,WAAW,yBAAyB;IACxC,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC;IACvC,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IAEjC,kDAAkD;IAClD,OAAO,CAAC,UAAU,CAAC,CAAuB;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;gBAE7C,OAAO,EAAE,yBAAyB;IAyB9C,OAAO,CAAC,SAAS;IAajB;;;;;OAKG;YACW,OAAO;IAiBrB;;;;;;;;;;OAUG;IACG,IAAI,CAAC,IAAI,SAAS,UAAU,EAAE,IAAI,SAAS,UAAU,EAAE,OAAO,EAAE;QACpE,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,IAAI,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAClC,GAAG,OAAO,CAAC,IAAI,CAAC;CAiFlB"}
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ /**
3
+ * JWT-bearer transport for the Hawcx management API (Path A: private_key_jwt).
4
+ *
5
+ * Each request is authenticated with a per-request EdDSA JWT whose `aud` is
6
+ * the full request URL, carrying a `body_sha256` claim over the EXACT bytes
7
+ * sent. This mirrors the wire contract verified end-to-end against hx_auth
8
+ * (see spec.md §management-api-auth / Python SDK Path A implementation).
9
+ *
10
+ * Construction:
11
+ * const transport = new JwtBearerTransport({
12
+ * baseUrl: 'https://api.hawcx.com',
13
+ * configId: 'your-config-id',
14
+ * clientId: 'your-client-id',
15
+ * oidcSigningKey: pkcs8Pem, // Ed25519 PKCS#8 PEM — same key registered in admin console
16
+ * kid: 'key-id',
17
+ * });
18
+ *
19
+ * The `http` constructor option accepts an injectable fetch-compatible function
20
+ * (same signature as the global `fetch`) for testing.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.JwtBearerTransport = void 0;
24
+ const node_crypto_1 = require("node:crypto");
25
+ const node_crypto_2 = require("node:crypto");
26
+ const jose_1 = require("jose");
27
+ const exceptions_1 = require("../delegation/exceptions");
28
+ /**
29
+ * Drop-in transport for the management API that authenticates via a per-request
30
+ * EdDSA JWT (`private_key_jwt`, Path A).
31
+ *
32
+ * The `send` method has the same name and signature as `DelegationTransport.send`
33
+ * so the factory can swap transports behind `StepUpClient` without any change to
34
+ * the business-method layer.
35
+ */
36
+ class JwtBearerTransport {
37
+ constructor(options) {
38
+ this.baseUrl = options.baseUrl.replace(/\/$/, '');
39
+ this.configId = options.configId;
40
+ this.kid = options.kid;
41
+ this.clientId = options.clientId;
42
+ this.jwtTtlSeconds = options.jwtTtlSeconds ?? 60;
43
+ this.timeoutMs = (options.timeoutSeconds ?? 15) * 1000;
44
+ this.http = options.http ?? ((...args) => fetch(...args));
45
+ const key = options.oidcSigningKey;
46
+ if (typeof key === 'string') {
47
+ // PKCS#8 PEM
48
+ this.importKeyFn = () => (0, jose_1.importPKCS8)(key, 'EdDSA');
49
+ }
50
+ else if (isJwk(key)) {
51
+ // Plain JWK object
52
+ this.importKeyFn = () => (0, jose_1.importJWK)(key, 'EdDSA');
53
+ }
54
+ else {
55
+ // Already a jose KeyLike / CryptoKey — wrap in a resolved promise.
56
+ const resolved = Promise.resolve(key);
57
+ this.importKeyFn = () => resolved;
58
+ }
59
+ }
60
+ // ── Key loading ────────────────────────────────────────────────────────────
61
+ importKey() {
62
+ if (!this.keyPromise) {
63
+ // Don't memoise a rejection — reset so the next call retries.
64
+ this.keyPromise = this.importKeyFn().catch((err) => {
65
+ this.keyPromise = undefined;
66
+ throw err;
67
+ });
68
+ }
69
+ return this.keyPromise;
70
+ }
71
+ // ── JWT minting ────────────────────────────────────────────────────────────
72
+ /**
73
+ * Mint a per-request EdDSA JWT.
74
+ *
75
+ * @param audience - full request URL (`baseUrl + endpoint`), pinned per-call
76
+ * @param bodySha256 - base64url (no-padding) of SHA-256 over the exact body bytes
77
+ */
78
+ async mintJwt(audience, bodySha256) {
79
+ const key = await this.importKey();
80
+ const nowSec = Math.floor(Date.now() / 1000);
81
+ return new jose_1.SignJWT({ body_sha256: bodySha256 })
82
+ .setProtectedHeader({ alg: 'EdDSA', kid: this.kid, typ: 'JWT' })
83
+ .setIssuer(this.clientId)
84
+ .setSubject(this.clientId)
85
+ .setAudience(audience)
86
+ .setIssuedAt(nowSec)
87
+ .setExpirationTime(nowSec + this.jwtTtlSeconds)
88
+ .setJti((0, node_crypto_1.randomUUID)())
89
+ .sign(key);
90
+ }
91
+ // ── Transport ──────────────────────────────────────────────────────────────
92
+ /**
93
+ * Send an authenticated POST to `endpoint` with `payload` serialised as JSON.
94
+ *
95
+ * Matches the signature of `DelegationTransport.send` so the two transports
96
+ * are drop-in substitutes behind `StepUpClient`.
97
+ *
98
+ * @param options.endpoint - API path, e.g. `/v1/management/stepup/start-token`
99
+ * @param options.payload - request body; serialised once and hashed; the
100
+ * EXACT same bytes are sent and hashed — no double-serialisation.
101
+ * @param options.headers - optional extra headers merged last (win over built-ins)
102
+ */
103
+ async send(options) {
104
+ const { endpoint, payload, headers: extraHeaders = {} } = options;
105
+ // Canonicalise body ONCE. The same Buffer is both hashed and sent.
106
+ const bodyBytes = Buffer.from(JSON.stringify(payload));
107
+ // SHA-256 → base64url without padding (RFC 7515 §2).
108
+ const hash = (0, node_crypto_2.createHash)('sha256').update(bodyBytes).digest();
109
+ const bodySha256 = hash.toString('base64url').replace(/=+$/, '');
110
+ const url = this.baseUrl + endpoint;
111
+ let jwt;
112
+ try {
113
+ jwt = await this.mintJwt(url, bodySha256);
114
+ }
115
+ catch (err) {
116
+ throw new exceptions_1.DelegationRequestError('Failed to sign management request', { cause: err });
117
+ }
118
+ // Extra headers are merged first so the transport's own auth/routing
119
+ // headers (Authorization, X-Config-Id, X-Hawcx-Protocol-Version) cannot
120
+ // be accidentally overridden by the caller's header bag.
121
+ const requestHeaders = {
122
+ ...extraHeaders,
123
+ 'Content-Type': 'application/json',
124
+ 'Authorization': `Bearer ${jwt}`,
125
+ 'X-Config-Id': this.configId,
126
+ 'X-Hawcx-Protocol-Version': '2',
127
+ };
128
+ let response;
129
+ let responseData;
130
+ // Bound every request with a timeout: a connected-but-silent server would
131
+ // otherwise hang the call indefinitely and can exhaust connection pools.
132
+ const controller = new AbortController();
133
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
134
+ try {
135
+ response = await this.http(url, {
136
+ method: 'POST',
137
+ headers: requestHeaders,
138
+ body: bodyBytes,
139
+ signal: controller.signal,
140
+ });
141
+ responseData = Buffer.from(await response.arrayBuffer());
142
+ }
143
+ catch (err) {
144
+ if (err instanceof exceptions_1.DelegationRequestError)
145
+ throw err;
146
+ throw new exceptions_1.DelegationRequestError('Request to management API failed', { cause: err });
147
+ }
148
+ finally {
149
+ clearTimeout(timer);
150
+ }
151
+ const text = responseData.toString('utf-8');
152
+ // Check the HTTP status BEFORE parsing JSON. A non-JSON error body (e.g. a
153
+ // WAF/proxy HTML 403) must still surface its status as a
154
+ // DelegationRequestError — not get masked as a JSON parse failure that the
155
+ // caller can't distinguish from a malformed 200.
156
+ if (response.status >= 400) {
157
+ let errorBody = text;
158
+ try {
159
+ const errJson = JSON.parse(text);
160
+ if (errJson?.detail)
161
+ errorBody = String(errJson.detail);
162
+ }
163
+ catch {
164
+ // Non-JSON error body — keep the raw text.
165
+ }
166
+ throw new exceptions_1.DelegationRequestError(`Management API returned ${response.status}`, {
167
+ statusCode: response.status,
168
+ responseBody: errorBody,
169
+ });
170
+ }
171
+ let parsed;
172
+ try {
173
+ parsed = JSON.parse(text);
174
+ }
175
+ catch (err) {
176
+ throw new exceptions_1.DelegationResponseError('Failed to parse management API response', { cause: err });
177
+ }
178
+ return parsed;
179
+ }
180
+ }
181
+ exports.JwtBearerTransport = JwtBearerTransport;
182
+ // ── helpers ──────────────────────────────────────────────────────────────────
183
+ /** Narrow check: is this value a plain JWK object (has `kty` string)? */
184
+ function isJwk(value) {
185
+ return (typeof value === 'object' &&
186
+ value !== null &&
187
+ typeof value.kty === 'string');
188
+ }
189
+ //# sourceMappingURL=jwt_transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt_transport.js","sourceRoot":"","sources":["../../src/management/jwt_transport.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,15 @@
1
- import { DelegationTransport } from '../delegation/transport';
1
+ import { type JsonObject, type SecureRequestOptions } from '../delegation/transport';
2
2
  import { DelegationKeyMaterial } from '../delegation/factory';
3
+ import { type JwtBearerTransportOptions } from '../management/jwt_transport';
3
4
  import { StepUpClientBaseOptions, StepUpConsumeOptions, StepUpConsumeResponse, StepUpStartOptions, StepUpStartTokenResponse } from './types';
5
+ /**
6
+ * Structural interface satisfied by both `DelegationTransport` (ECIES) and
7
+ * `JwtBearerTransport` (private_key_jwt). Allows `StepUpClient` to accept
8
+ * either transport without a hard dependency on the concrete types.
9
+ */
10
+ interface StepUpTransport {
11
+ send<TReq extends JsonObject, TRes extends JsonObject>(options: Pick<SecureRequestOptions<TReq>, 'endpoint' | 'payload' | 'headers'>): Promise<TRes>;
12
+ }
4
13
  export interface StepUpClientSecretKeyOptions extends StepUpClientBaseOptions {
5
14
  secretKey: string;
6
15
  apiKey?: string;
@@ -8,19 +17,69 @@ export interface StepUpClientSecretKeyOptions extends StepUpClientBaseOptions {
8
17
  export type StepUpClientKeyOptions = StepUpClientBaseOptions & DelegationKeyMaterial & {
9
18
  apiKey?: string;
10
19
  };
20
+ /**
21
+ * Options for {@link StepUpClient.withPrivateKeyJwt}. Combines the
22
+ * JWT-bearer transport credentials with the standard step-up base options.
23
+ */
24
+ export interface StepUpClientPrivateKeyJwtOptions extends StepUpClientBaseOptions {
25
+ /** Ed25519 private signing key (PKCS#8 PEM, JWK object, or jose KeyLike). */
26
+ oidcSigningKey: JwtBearerTransportOptions['oidcSigningKey'];
27
+ /** Key ID embedded in the JWT `kid` header. */
28
+ kid: string;
29
+ /** OAuth client ID (`iss` / `sub` in the per-request JWT). */
30
+ clientId: string;
31
+ /** Tenant config identifier; forwarded as `X-Config-Id`. */
32
+ configId: string;
33
+ /** Optional API key forwarded as `apikey` header. */
34
+ apiKey?: string;
35
+ /** JWT time-to-live in seconds (default: 60). */
36
+ jwtTtlSeconds?: number;
37
+ }
11
38
  export declare class StepUpClient {
12
39
  private transport;
13
40
  private options;
14
41
  private apiKey?;
15
42
  constructor(options: {
16
- transport: DelegationTransport;
43
+ transport: StepUpTransport;
17
44
  clientOptions: StepUpClientBaseOptions;
18
45
  apiKey?: string;
19
46
  });
47
+ /**
48
+ * @deprecated since 5.2.0 — the ECIES secret-key credential format is
49
+ * proprietary and will be removed in a future major version. Migrate to
50
+ * {@link StepUpClient.withPrivateKeyJwt}, which reuses the standard OIDC
51
+ * Ed25519 `private_key_jwt` signing key already registered in the admin
52
+ * console (one key, standards-based).
53
+ */
20
54
  static fromSecretKey(options: StepUpClientSecretKeyOptions): StepUpClient;
55
+ /**
56
+ * @deprecated since 5.2.0 — the ECIES key-material format is proprietary
57
+ * and will be removed in a future major version. Migrate to
58
+ * {@link StepUpClient.withPrivateKeyJwt}.
59
+ */
21
60
  static fromKeys(options: StepUpClientKeyOptions): StepUpClient;
61
+ /**
62
+ * Build a `StepUpClient` authenticated via EdDSA `private_key_jwt` (Path A).
63
+ *
64
+ * Reuses the same Ed25519 signing key registered in the Hawcx admin console
65
+ * for OIDC `private_key_jwt` — one key, standards-based, no separate ECIES
66
+ * credential blob required.
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * const stepUp = StepUpClient.withPrivateKeyJwt({
71
+ * baseUrl: 'https://api.hawcx.com',
72
+ * configId: process.env.HAWCX_CONFIG_ID!,
73
+ * clientId: process.env.HAWCX_CLIENT_ID!,
74
+ * oidcSigningKey: JSON.parse(process.env.HAWCX_PRIVATE_JWK!),
75
+ * kid: 'your-key-id',
76
+ * });
77
+ * ```
78
+ */
79
+ static withPrivateKeyJwt(options: StepUpClientPrivateKeyJwtOptions): StepUpClient;
22
80
  private buildExtraHeaders;
23
81
  startToken(options: StepUpStartOptions): Promise<StepUpStartTokenResponse>;
24
82
  consumeReceipt(options: StepUpConsumeOptions): Promise<StepUpConsumeResponse>;
25
83
  }
84
+ export {};
26
85
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/stepup/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAuD,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnH,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,4BAA6B,SAAQ,uBAAuB;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,sBAAsB,GAAG,uBAAuB,GAAG,qBAAqB,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3G,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,OAAO,EAAE;QACnB,SAAS,EAAE,mBAAmB,CAAC;QAC/B,aAAa,EAAE,uBAAuB,CAAC;QACvC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAMD,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,4BAA4B,GAAG,YAAY;IAMzE,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,YAAY;IAM9D,OAAO,CAAC,iBAAiB;IAmBnB,UAAU,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAuB1E,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAoBpF"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/stepup/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAuD,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnH,OAAO,EAAsB,KAAK,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACjG,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,UAAU,eAAe;IACvB,IAAI,CAAC,IAAI,SAAS,UAAU,EAAE,IAAI,SAAS,UAAU,EACnD,OAAO,EAAE,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC,GAC5E,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,MAAM,WAAW,4BAA6B,SAAQ,uBAAuB;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,sBAAsB,GAAG,uBAAuB,GAAG,qBAAqB,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3G;;;GAGG;AACH,MAAM,WAAW,gCAAiC,SAAQ,uBAAuB;IAC/E,6EAA6E;IAC7E,cAAc,EAAE,yBAAyB,CAAC,gBAAgB,CAAC,CAAC;IAC5D,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,OAAO,EAAE;QACnB,SAAS,EAAE,eAAe,CAAC;QAC3B,aAAa,EAAE,uBAAuB,CAAC;QACvC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAMD;;;;;;OAMG;IACH,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,4BAA4B,GAAG,YAAY;IAezE;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,YAAY;IAe9D;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,gCAAgC,GAAG,YAAY;IAiBjF,OAAO,CAAC,iBAAiB;IAmBnB,UAAU,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAuB1E,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAoBpF"}
@@ -3,22 +3,81 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StepUpClient = void 0;
4
4
  const factory_1 = require("../delegation/factory");
5
5
  const exceptions_1 = require("../delegation/exceptions");
6
+ const jwt_transport_1 = require("../management/jwt_transport");
6
7
  class StepUpClient {
7
8
  constructor(options) {
8
9
  this.transport = options.transport;
9
10
  this.options = options.clientOptions;
10
11
  this.apiKey = options.apiKey;
11
12
  }
13
+ /**
14
+ * @deprecated since 5.2.0 — the ECIES secret-key credential format is
15
+ * proprietary and will be removed in a future major version. Migrate to
16
+ * {@link StepUpClient.withPrivateKeyJwt}, which reuses the standard OIDC
17
+ * Ed25519 `private_key_jwt` signing key already registered in the admin
18
+ * console (one key, standards-based).
19
+ */
12
20
  static fromSecretKey(options) {
21
+ if (!fromSecretKeyWarned) {
22
+ fromSecretKeyWarned = true;
23
+ process.emitWarning('[@hawcx/oauth-client] StepUpClient.fromSecretKey() is deprecated since 5.2.0. ' +
24
+ 'Migrate to StepUpClient.withPrivateKeyJwt() (standards-based Ed25519 private_key_jwt). ' +
25
+ 'fromSecretKey() will be removed in a future major version.', 'DeprecationWarning');
26
+ }
13
27
  const { apiKey } = options;
14
28
  const transport = (0, factory_1.buildTransportFromSecretKey)(options);
15
29
  return new StepUpClient({ transport, clientOptions: options, apiKey });
16
30
  }
31
+ /**
32
+ * @deprecated since 5.2.0 — the ECIES key-material format is proprietary
33
+ * and will be removed in a future major version. Migrate to
34
+ * {@link StepUpClient.withPrivateKeyJwt}.
35
+ */
17
36
  static fromKeys(options) {
37
+ if (!fromKeysWarned) {
38
+ fromKeysWarned = true;
39
+ process.emitWarning('[@hawcx/oauth-client] StepUpClient.fromKeys() is deprecated since 5.2.0. ' +
40
+ 'Migrate to StepUpClient.withPrivateKeyJwt() (standards-based Ed25519 private_key_jwt). ' +
41
+ 'fromKeys() will be removed in a future major version.', 'DeprecationWarning');
42
+ }
18
43
  const { apiKey } = options;
19
44
  const transport = (0, factory_1.buildTransportFromKeys)(options);
20
45
  return new StepUpClient({ transport, clientOptions: options, apiKey });
21
46
  }
47
+ /**
48
+ * Build a `StepUpClient` authenticated via EdDSA `private_key_jwt` (Path A).
49
+ *
50
+ * Reuses the same Ed25519 signing key registered in the Hawcx admin console
51
+ * for OIDC `private_key_jwt` — one key, standards-based, no separate ECIES
52
+ * credential blob required.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const stepUp = StepUpClient.withPrivateKeyJwt({
57
+ * baseUrl: 'https://api.hawcx.com',
58
+ * configId: process.env.HAWCX_CONFIG_ID!,
59
+ * clientId: process.env.HAWCX_CLIENT_ID!,
60
+ * oidcSigningKey: JSON.parse(process.env.HAWCX_PRIVATE_JWK!),
61
+ * kid: 'your-key-id',
62
+ * });
63
+ * ```
64
+ */
65
+ static withPrivateKeyJwt(options) {
66
+ const { apiKey, oidcSigningKey, kid, clientId, configId, jwtTtlSeconds, ...clientOptions } = options;
67
+ const transport = new jwt_transport_1.JwtBearerTransport({
68
+ baseUrl: clientOptions.baseUrl,
69
+ configId,
70
+ clientId,
71
+ oidcSigningKey,
72
+ kid,
73
+ jwtTtlSeconds,
74
+ // Thread the request timeout through to the transport — without this it
75
+ // stays in clientOptions and the JWT transport falls back to its 15s
76
+ // default regardless of what the caller passed (parity with fromKeys).
77
+ timeoutSeconds: clientOptions.timeoutSeconds,
78
+ });
79
+ return new StepUpClient({ transport, clientOptions, apiKey });
80
+ }
22
81
  buildExtraHeaders() {
23
82
  const headers = {
24
83
  'X-Hawcx-Protocol-Version': '1',
@@ -75,4 +134,9 @@ class StepUpClient {
75
134
  }
76
135
  }
77
136
  exports.StepUpClient = StepUpClient;
137
+ // Module-level flags so the deprecation warning fires at most once per process
138
+ // (matches the clearCache() pattern in oauth.ts which warns once per instance;
139
+ // here we warn once per process since the factory is static).
140
+ let fromSecretKeyWarned = false;
141
+ let fromKeysWarned = false;
78
142
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/stepup/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/stepup/client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hawcx/oauth-client",
3
- "version": "5.1.0",
3
+ "version": "5.2.0",
4
4
  "description": "Simple OAuth client for Hawcx authentication with delegation support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -47,6 +47,7 @@
47
47
  "files": [
48
48
  "dist",
49
49
  "README.md",
50
+ "CHANGELOG.md",
50
51
  "LICENSE"
51
52
  ]
52
53
  }