@hawcx/oauth-client 4.0.1 → 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 +253 -0
- package/LICENSE +22 -0
- package/README.md +179 -26
- package/dist/client-assertion.d.ts +45 -0
- package/dist/client-assertion.d.ts.map +1 -0
- package/dist/client-assertion.js +141 -0
- package/dist/client-assertion.js.map +1 -0
- package/dist/delegation/hawcx.d.ts +0 -8
- package/dist/delegation/hawcx.d.ts.map +1 -1
- package/dist/delegation/hawcx.js +0 -17
- package/dist/delegation/hawcx.js.map +1 -1
- package/dist/delegation/index.d.ts +1 -1
- package/dist/delegation/index.d.ts.map +1 -1
- package/dist/delegation/index.js.map +1 -1
- package/dist/errors.d.ts +51 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +50 -6
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/management/jwt_transport.d.ts +109 -0
- package/dist/management/jwt_transport.d.ts.map +1 -0
- package/dist/management/jwt_transport.js +189 -0
- package/dist/management/jwt_transport.js.map +1 -0
- package/dist/oauth.d.ts +188 -21
- package/dist/oauth.d.ts.map +1 -1
- package/dist/oauth.js +390 -43
- package/dist/oauth.js.map +1 -1
- package/dist/stepup/client.d.ts +61 -2
- package/dist/stepup/client.d.ts.map +1 -1
- package/dist/stepup/client.js +69 -11
- package/dist/stepup/client.js.map +1 -1
- package/dist/stepup/types.d.ts +2 -3
- package/dist/stepup/types.d.ts.map +1 -1
- package/package.json +12 -13
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ClientAssertionSigner = exports.CLIENT_ASSERTION_TYPE = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* RFC 7523 / OIDC Core §9 `client_assertion` signer for the
|
|
6
|
+
* `private_key_jwt` token-endpoint authentication method.
|
|
7
|
+
*
|
|
8
|
+
* EdDSA over Ed25519 is the only algorithm the Hawcx OP accepts at the token
|
|
9
|
+
* endpoint, so it is the only one supported here. Obtain an instance via
|
|
10
|
+
* {@link ClientAssertionSigner.ed25519FromJwk} (or `ed25519FromPem` /
|
|
11
|
+
* `ed25519`) and attach it with `HawcxOAuth.withClientAssertion(signer)`.
|
|
12
|
+
*
|
|
13
|
+
* @beta This `private_key_jwt` surface is experimental and may change before
|
|
14
|
+
* it is marked stable.
|
|
15
|
+
*/
|
|
16
|
+
const node_crypto_1 = require("node:crypto");
|
|
17
|
+
const jose_1 = require("jose");
|
|
18
|
+
/** RFC 7523 §2.2 assertion type for the `private_key_jwt` method. */
|
|
19
|
+
exports.CLIENT_ASSERTION_TYPE = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer';
|
|
20
|
+
const DEFAULT_LIFETIME_SECONDS = 60;
|
|
21
|
+
const MAX_LIFETIME_SECONDS = 120; // OP cap (ASSERTION_MAX_TTL_SECONDS)
|
|
22
|
+
class ClientAssertionSigner {
|
|
23
|
+
constructor(importKeyFn, kid, lifetimeSeconds) {
|
|
24
|
+
this.importKeyFn = importKeyFn;
|
|
25
|
+
this.kid = kid;
|
|
26
|
+
this.lifetimeSeconds = lifetimeSeconds;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build a signer from an Ed25519 *private* JWK (RFC 8037):
|
|
30
|
+
* `{ kty: 'OKP', crv: 'Ed25519', d, x, kid }`. The `kid` is read from the
|
|
31
|
+
* JWK. This is the canonical Hawcx key format (what the admin console
|
|
32
|
+
* generates/downloads). Accepts either a JWK object or its JSON string.
|
|
33
|
+
*/
|
|
34
|
+
static ed25519FromJwk(privateJwk) {
|
|
35
|
+
let jwk;
|
|
36
|
+
if (typeof privateJwk === 'string') {
|
|
37
|
+
try {
|
|
38
|
+
jwk = JSON.parse(privateJwk);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
throw new Error(`private JWK is not valid JSON: ${String(err)}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
jwk = privateJwk;
|
|
46
|
+
}
|
|
47
|
+
if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519') {
|
|
48
|
+
throw new Error(`client assertion key must be an Ed25519 OKP JWK (got kty=${String(jwk.kty)}, crv=${String(jwk.crv)})`);
|
|
49
|
+
}
|
|
50
|
+
if (typeof jwk.d !== 'string' || jwk.d.length === 0) {
|
|
51
|
+
throw new Error("client assertion JWK has no 'd' (not a private key)");
|
|
52
|
+
}
|
|
53
|
+
if (typeof jwk.kid !== 'string' || jwk.kid.length === 0) {
|
|
54
|
+
throw new Error("client assertion JWK is missing 'kid'");
|
|
55
|
+
}
|
|
56
|
+
const kid = jwk.kid;
|
|
57
|
+
return new ClientAssertionSigner(() => (0, jose_1.importJWK)(jwk, 'EdDSA'), kid, DEFAULT_LIFETIME_SECONDS);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Build a signer from a PKCS#8 PEM-encoded Ed25519 private key plus its `kid`.
|
|
61
|
+
* The key type is validated (must be Ed25519) on first use.
|
|
62
|
+
*/
|
|
63
|
+
static ed25519FromPem(pkcs8Pem, kid) {
|
|
64
|
+
if (!kid)
|
|
65
|
+
throw new Error('kid is required');
|
|
66
|
+
return new ClientAssertionSigner(async () => {
|
|
67
|
+
let key;
|
|
68
|
+
try {
|
|
69
|
+
key = await (0, jose_1.importPKCS8)(pkcs8Pem, 'EdDSA');
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
throw new Error(`not a valid PKCS#8 PEM private key: ${String(err)}`);
|
|
73
|
+
}
|
|
74
|
+
assertEd25519(key);
|
|
75
|
+
return key;
|
|
76
|
+
}, kid, DEFAULT_LIFETIME_SECONDS);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Build a signer from an already-loaded Ed25519 private `KeyObject`
|
|
80
|
+
* (e.g. from `crypto.createPrivateKey(...)`) plus its `kid`.
|
|
81
|
+
*/
|
|
82
|
+
static ed25519(privateKey, kid) {
|
|
83
|
+
if (!kid)
|
|
84
|
+
throw new Error('kid is required');
|
|
85
|
+
if (privateKey.asymmetricKeyType !== 'ed25519') {
|
|
86
|
+
throw new Error(`private key must be Ed25519 (got ${String(privateKey.asymmetricKeyType)})`);
|
|
87
|
+
}
|
|
88
|
+
// Round-trip through a JWK so the key flows through jose's own importJWK
|
|
89
|
+
// rather than an unchecked cast into jose's KeyLike union.
|
|
90
|
+
const jwk = privateKey.export({ format: 'jwk' });
|
|
91
|
+
return new ClientAssertionSigner(() => (0, jose_1.importJWK)(jwk, 'EdDSA'), kid, DEFAULT_LIFETIME_SECONDS);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Return a copy of this signer using `seconds` as the assertion lifetime
|
|
95
|
+
* (iat→exp). Clamped to [1, 120] (the OP maximum). Defaults to 60; most
|
|
96
|
+
* callers never need this.
|
|
97
|
+
*/
|
|
98
|
+
withLifetimeSeconds(seconds) {
|
|
99
|
+
const clamped = Math.max(1, Math.min(MAX_LIFETIME_SECONDS, Math.floor(seconds)));
|
|
100
|
+
return new ClientAssertionSigner(this.importKeyFn, this.kid, clamped);
|
|
101
|
+
}
|
|
102
|
+
importKey() {
|
|
103
|
+
if (!this.keyPromise) {
|
|
104
|
+
// Don't memoise a rejection — a transient/structural import failure must
|
|
105
|
+
// not permanently poison the signer. Reset so the next sign() retries.
|
|
106
|
+
this.keyPromise = this.importKeyFn().catch((err) => {
|
|
107
|
+
this.keyPromise = undefined;
|
|
108
|
+
throw err;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return this.keyPromise;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Build and Ed25519-sign the `client_assertion` JWT for one token exchange.
|
|
115
|
+
*
|
|
116
|
+
* @param clientId - becomes `iss` and `sub` (RFC 7523 §3)
|
|
117
|
+
* @param audience - the OP's token endpoint, exactly as advertised in
|
|
118
|
+
* discovery (the OP pins `aud` to that string)
|
|
119
|
+
*/
|
|
120
|
+
async sign(clientId, audience) {
|
|
121
|
+
const key = await this.importKey();
|
|
122
|
+
return new jose_1.SignJWT({})
|
|
123
|
+
.setProtectedHeader({ alg: 'EdDSA', typ: 'JWT', kid: this.kid })
|
|
124
|
+
.setIssuer(clientId)
|
|
125
|
+
.setSubject(clientId)
|
|
126
|
+
.setAudience(audience)
|
|
127
|
+
.setIssuedAt()
|
|
128
|
+
.setExpirationTime(`${this.lifetimeSeconds}s`)
|
|
129
|
+
.setJti((0, node_crypto_1.randomUUID)())
|
|
130
|
+
.sign(key);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
exports.ClientAssertionSigner = ClientAssertionSigner;
|
|
134
|
+
function assertEd25519(key) {
|
|
135
|
+
// Node's importPKCS8 yields a KeyObject; reject non-Ed25519 with a clean message.
|
|
136
|
+
const type = key.asymmetricKeyType;
|
|
137
|
+
if (type !== undefined && type !== 'ed25519') {
|
|
138
|
+
throw new Error(`PEM key is not Ed25519 (got ${String(type)})`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=client-assertion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-assertion.js","sourceRoot":"","sources":["../src/client-assertion.ts"],"names":[],"mappings":"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"}
|
|
@@ -42,12 +42,6 @@ export interface MfaVerifyOptions {
|
|
|
42
42
|
/** One-time password entered by user (6 digits) */
|
|
43
43
|
otp: string;
|
|
44
44
|
}
|
|
45
|
-
export interface UpdatePhoneOptions {
|
|
46
|
-
/** User identifier (userid or email) */
|
|
47
|
-
userId: string;
|
|
48
|
-
/** New phone number in E.164 format (e.g. "+14155551234"). Pass null to clear. */
|
|
49
|
-
newPhoneNumber: string | null;
|
|
50
|
-
}
|
|
51
45
|
export interface DeviceOperationOptions {
|
|
52
46
|
/** User identifier (typically email address) */
|
|
53
47
|
userId: string;
|
|
@@ -83,8 +77,6 @@ export declare class DelegationClient {
|
|
|
83
77
|
};
|
|
84
78
|
readonly users: {
|
|
85
79
|
getCredentials: (userId: string) => Promise<JsonObject>;
|
|
86
|
-
getPhone: (userId: string) => Promise<JsonObject>;
|
|
87
|
-
updatePhone: (options: UpdatePhoneOptions) => Promise<JsonObject>;
|
|
88
80
|
};
|
|
89
81
|
readonly devices: {
|
|
90
82
|
list: (userId: string) => Promise<JsonObject>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hawcx.d.ts","sourceRoot":"","sources":["../../src/delegation/hawcx.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAuD,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAGvG,oBAAY,SAAS;IACnB,KAAK,UAAU;IACf,GAAG,QAAQ;IACX,IAAI,SAAS;CACd;AAED,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1C,MAAM,WAAW,2BAA2B;IAC1C,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gCAAiC,SAAQ,2BAA2B;IACnF,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,0BAA0B,GAAG,2BAA2B,GAAG,qBAAqB,CAAC;AAE7F,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,SAAS,EAAE,SAAS,GAAG,MAAM,CAAC;IAC9B,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"hawcx.d.ts","sourceRoot":"","sources":["../../src/delegation/hawcx.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAuD,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAGvG,oBAAY,SAAS;IACnB,KAAK,UAAU;IACf,GAAG,QAAQ;IACX,IAAI,SAAS;CACd;AAED,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1C,MAAM,WAAW,2BAA2B;IAC1C,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gCAAiC,SAAQ,2BAA2B;IACnF,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,0BAA0B,GAAG,2BAA2B,GAAG,qBAAqB,CAAC;AAE7F,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,SAAS,EAAE,SAAS,GAAG,MAAM,CAAC;IAC9B,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,sBAAsB;IACrC,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,wBAAwB,CAAC,QAAQ,SAAS,UAAU;IACnE,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,OAAO,EAAE,QAAQ,CAAC;IAClB,6DAA6D;IAC7D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,MAAM,CAAC,CAAS;IAExB,SAAgB,OAAO,EAAE,MAAM,CAAC;gBAEpB,OAAO,EAAE;QAAE,SAAS,EAAE,mBAAmB,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAMzF,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,gCAAgC,GAAG,gBAAgB;IAMjF,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,0BAA0B,GAAG,gBAAgB;IAMtE,OAAO,CAAC,gBAAgB;IAQlB,OAAO,CAAC,IAAI,SAAS,UAAU,EAAE,IAAI,SAAS,UAAU,EAC5D,OAAO,EAAE,wBAAwB,CAAC,IAAI,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC;IAKhB,SAAgB,GAAG;4BACS,kBAAkB,KAAG,OAAO,CAAC,UAAU,CAAC;0BAmC1C,gBAAgB,KAAG,OAAO,CAAC,UAAU,CAAC;MAkB9D;IAEF,SAAgB,KAAK;iCACY,MAAM,KAAG,OAAO,CAAC,UAAU,CAAC;MAO3D;IAEF,SAAgB,OAAO;uBACA,MAAM,KAAG,OAAO,CAAC,UAAU,CAAC;0BAOzB,sBAAsB,KAAG,OAAO,CAAC,UAAU,CAAC;4BAO1C,sBAAsB,KAAG,OAAO,CAAC,UAAU,CAAC;0BAO9C,sBAAsB,KAAG,OAAO,CAAC,UAAU,CAAC;MAOpE;CACH"}
|
package/dist/delegation/hawcx.js
CHANGED
|
@@ -65,23 +65,6 @@ class DelegationClient {
|
|
|
65
65
|
payload,
|
|
66
66
|
});
|
|
67
67
|
},
|
|
68
|
-
getPhone: async (userId) => {
|
|
69
|
-
const payload = { userid: userId };
|
|
70
|
-
return await this.request({
|
|
71
|
-
endpoint: '/hc_auth/v5/management/users/phone',
|
|
72
|
-
payload,
|
|
73
|
-
});
|
|
74
|
-
},
|
|
75
|
-
updatePhone: async (options) => {
|
|
76
|
-
const payload = {
|
|
77
|
-
userid: options.userId,
|
|
78
|
-
new_phone_number: options.newPhoneNumber,
|
|
79
|
-
};
|
|
80
|
-
return await this.request({
|
|
81
|
-
endpoint: '/hc_auth/v5/management/users/phone',
|
|
82
|
-
payload,
|
|
83
|
-
});
|
|
84
|
-
},
|
|
85
68
|
};
|
|
86
69
|
this.devices = {
|
|
87
70
|
list: async (userId) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hawcx.js","sourceRoot":"","sources":["../../src/delegation/hawcx.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAGH,uCAAuG;AACvG,6CAAsD;AAEtD,IAAY,SAIX;AAJD,WAAY,SAAS;IACnB,4BAAe,CAAA;IACf,wBAAW,CAAA;IACX,0BAAa,CAAA;AACf,CAAC,EAJW,SAAS,yBAAT,SAAS,QAIpB;
|
|
1
|
+
{"version":3,"file":"hawcx.js","sourceRoot":"","sources":["../../src/delegation/hawcx.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Hawcx OAuth Client SDK - Delegation Module
|
|
3
3
|
*/
|
|
4
4
|
export { DelegationClient, MfaMethod, } from './hawcx';
|
|
5
|
-
export type { DelegationClientBaseOptions, DelegationClientSecretKeyOptions, DelegationClientKeyOptions, MfaInitiateOptions, MfaVerifyOptions,
|
|
5
|
+
export type { DelegationClientBaseOptions, DelegationClientSecretKeyOptions, DelegationClientKeyOptions, MfaInitiateOptions, MfaVerifyOptions, DeviceOperationOptions, DelegationRequestOptions, } from './hawcx';
|
|
6
6
|
export { parseHawcxSecretKey, generateCredentialBlob, } from './credentials';
|
|
7
7
|
export type { ParsedCredentials, HawcxCredentialBlob, } from './credentials';
|
|
8
8
|
export { DelegationError, DelegationCryptoError, DelegationRequestError, DelegationResponseError, } from './exceptions';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/delegation/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,SAAS,GACV,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,2BAA2B,EAC3B,gCAAgC,EAChC,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,EAChB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/delegation/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,SAAS,GACV,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,2BAA2B,EAC3B,gCAAgC,EAChC,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/delegation/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,iCAGiB;AAFf,yGAAA,gBAAgB,OAAA;AAChB,kGAAA,SAAS,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/delegation/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,iCAGiB;AAFf,yGAAA,gBAAgB,OAAA;AAChB,kGAAA,SAAS,OAAA;AAYX,6CAGuB;AAFrB,kHAAA,mBAAmB,OAAA;AACnB,qHAAA,sBAAsB,OAAA;AAOxB,2CAKsB;AAJpB,6GAAA,eAAe,OAAA;AACf,mHAAA,qBAAqB,OAAA;AACrB,oHAAA,sBAAsB,OAAA;AACtB,qHAAA,uBAAuB,OAAA"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,14 +1,62 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Hawcx OAuth Errors
|
|
3
3
|
*/
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Optional structured fields shared across the Hawcx OAuth error hierarchy.
|
|
6
|
+
* `error` is a stable machine-readable code callers can dispatch on (e.g.
|
|
7
|
+
* `'state_mismatch'`, `'state_missing'`, or an IdP-supplied OAuth error such as
|
|
8
|
+
* `'access_denied'`); `errorDescription` is the human-readable detail when one
|
|
9
|
+
* is available. Both are optional and never affect `.message`.
|
|
10
|
+
*/
|
|
11
|
+
export interface HawcxOAuthErrorFields {
|
|
12
|
+
/** Machine-readable error code (e.g. `'state_mismatch'`, `'access_denied'`). */
|
|
13
|
+
error?: string;
|
|
14
|
+
/** Human-readable error description, when one is available. */
|
|
15
|
+
errorDescription?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Canonical root for every Hawcx SDK error, aligned with the Java/Python SDKs
|
|
19
|
+
* (`HawcxError`). Catch this to handle any SDK-originated failure.
|
|
20
|
+
*/
|
|
21
|
+
export declare class HawcxError extends Error {
|
|
5
22
|
constructor(message: string);
|
|
6
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Historical base, retained for back-compat. Now a subclass of {@link HawcxError};
|
|
26
|
+
* every SDK error is catchable via either. New code can catch `HawcxError`.
|
|
27
|
+
*
|
|
28
|
+
* Carries optional structured {@link HawcxOAuthErrorFields} (`error` /
|
|
29
|
+
* `errorDescription`) so callers can dispatch on a stable code without parsing
|
|
30
|
+
* `.message`. These are populated at the relevant raise sites and never alter
|
|
31
|
+
* the thrown message string.
|
|
32
|
+
*/
|
|
33
|
+
export declare class HawcxOAuthError extends HawcxError {
|
|
34
|
+
/** Machine-readable error code, when set at the raise site. */
|
|
35
|
+
readonly error?: string;
|
|
36
|
+
/** Human-readable error description, when available. */
|
|
37
|
+
readonly errorDescription?: string;
|
|
38
|
+
constructor(message: string, fields?: HawcxOAuthErrorFields);
|
|
39
|
+
}
|
|
7
40
|
export declare class TokenExchangeError extends HawcxOAuthError {
|
|
8
41
|
readonly statusCode?: number;
|
|
9
|
-
constructor(message: string, statusCode?: number);
|
|
42
|
+
constructor(message: string, statusCode?: number, fields?: HawcxOAuthErrorFields);
|
|
10
43
|
}
|
|
11
44
|
export declare class TokenVerificationError extends HawcxOAuthError {
|
|
12
|
-
constructor(message: string);
|
|
45
|
+
constructor(message: string, fields?: HawcxOAuthErrorFields);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Thrown when OIDC discovery (`HawcxOAuth.fromIssuer`) cannot resolve a usable
|
|
49
|
+
* provider configuration — DNS / TLS / network failure, non-2xx response from
|
|
50
|
+
* `/.well-known/openid-configuration`, malformed JSON, or a discovery document
|
|
51
|
+
* missing required fields (`token_endpoint`, `jwks_uri`,
|
|
52
|
+
* `id_token_signing_alg_values_supported`).
|
|
53
|
+
*
|
|
54
|
+
* The original failure (when present) is attached as `cause`, so the full
|
|
55
|
+
* diagnostic stack survives.
|
|
56
|
+
*/
|
|
57
|
+
export declare class DiscoveryError extends HawcxOAuthError {
|
|
58
|
+
constructor(message: string, options?: {
|
|
59
|
+
cause?: unknown;
|
|
60
|
+
} & HawcxOAuthErrorFields);
|
|
13
61
|
}
|
|
14
62
|
//# sourceMappingURL=errors.d.ts.map
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,qBAAa,UAAW,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;GAQG;AACH,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,wDAAwD;IACxD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;gBAEvB,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,qBAAqB;CAM5D;AAED,qBAAa,kBAAmB,SAAQ,eAAe;IACrD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,qBAAqB;CAKjF;AAED,qBAAa,sBAAuB,SAAQ,eAAe;gBAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,qBAAqB;CAI5D;AAED;;;;;;;;;GASG;AACH,qBAAa,cAAe,SAAQ,eAAe;gBACrC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,qBAAqB;CAOnF"}
|
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
|
-
|
|
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
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";AAAA;;GAEG;;;
|
|
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 = "
|
|
22
|
+
export declare const VERSION = "5.2.0";
|
|
21
23
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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 = '
|
|
47
|
+
exports.VERSION = '5.2.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;
|
|
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"}
|
|
@@ -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"}
|