ehbp 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -7
- package/dist/cjs/client.d.ts +2 -0
- package/dist/cjs/client.d.ts.map +1 -1
- package/dist/cjs/client.js +28 -5
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/derive.d.ts.map +1 -1
- package/dist/cjs/derive.js +3 -3
- package/dist/cjs/derive.js.map +1 -1
- package/dist/cjs/errors.d.ts +32 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/cjs/errors.js +48 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/identity.d.ts +9 -0
- package/dist/cjs/identity.d.ts.map +1 -1
- package/dist/cjs/identity.js +23 -21
- package/dist/cjs/identity.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/protocol.d.ts +2 -0
- package/dist/cjs/protocol.d.ts.map +1 -1
- package/dist/cjs/protocol.js +2 -0
- package/dist/cjs/protocol.js.map +1 -1
- package/dist/esm/client.d.ts +2 -0
- package/dist/esm/client.d.ts.map +1 -1
- package/dist/esm/client.js +28 -5
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/derive.d.ts.map +1 -1
- package/dist/esm/derive.js +1 -1
- package/dist/esm/derive.js.map +1 -1
- package/dist/esm/errors.d.ts +32 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +41 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/identity.d.ts +9 -0
- package/dist/esm/identity.d.ts.map +1 -1
- package/dist/esm/identity.js +23 -21
- package/dist/esm/identity.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/protocol.d.ts +2 -0
- package/dist/esm/protocol.d.ts.map +1 -1
- package/dist/esm/protocol.js +2 -0
- package/dist/esm/protocol.js.map +1 -1
- package/dist/esm/test/client.test.js +124 -1
- package/dist/esm/test/client.test.js.map +1 -1
- package/dist/esm/test/identity.test.js +4 -4
- package/dist/esm/test/identity.test.js.map +1 -1
- package/dist/esm/test/security.test.js +2 -1
- package/dist/esm/test/security.test.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -10,11 +10,13 @@ EHBP encrypts HTTP request and response bodies end-to-end using HPKE ([RFC 9180]
|
|
|
10
10
|
npm install ehbp
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Compatible Runtimes
|
|
14
14
|
|
|
15
|
-
- Node.js 20+
|
|
16
|
-
-
|
|
15
|
+
- **Node.js** 20+
|
|
16
|
+
- **Bun** 1.x+
|
|
17
|
+
- **Browsers** with ES2020 support
|
|
17
18
|
|
|
19
|
+
All HPKE key operations use [`@noble/curves`](https://github.com/paulmillr/noble-curves) (via `@panva/hpke-noble`) instead of WebCrypto, so X25519 support in the runtime's `crypto.subtle` is **not** required.
|
|
18
20
|
|
|
19
21
|
## Quick Start
|
|
20
22
|
|
|
@@ -75,10 +77,6 @@ await transport.delete('/users/123');
|
|
|
75
77
|
</script>
|
|
76
78
|
```
|
|
77
79
|
|
|
78
|
-
## Requirements
|
|
79
|
-
|
|
80
|
-
- Node.js 20+ or modern browsers with Web Crypto API
|
|
81
|
-
|
|
82
80
|
## Development
|
|
83
81
|
|
|
84
82
|
```sh
|
package/dist/cjs/client.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export declare class Transport {
|
|
|
11
11
|
* Create a new transport by fetching server public key.
|
|
12
12
|
*/
|
|
13
13
|
static create(serverURL: string): Promise<Transport>;
|
|
14
|
+
private static isProblemJSONContentType;
|
|
15
|
+
private static checkKeyConfigMismatch;
|
|
14
16
|
/**
|
|
15
17
|
* Get the server identity
|
|
16
18
|
*/
|
package/dist/cjs/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAOhC;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,cAAc,CAAW;IACjC,OAAO,CAAC,UAAU,CAAS;gBAEf,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM;IAKxD;;OAEG;WACU,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAuB1D,OAAO,CAAC,MAAM,CAAC,wBAAwB;mBAQlB,sBAAsB;IAiB3C;;OAEG;IACH,iBAAiB,IAAI,QAAQ;IAI7B;;OAEG;IACH,kBAAkB,IAAI,GAAG;IAIzB;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAI9C;;OAEG;IACG,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAsE9E;;OAEG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAInE;;OAEG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIrF;;OAEG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIpF;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;CAGvE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAE3E"}
|
package/dist/cjs/client.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.Transport = void 0;
|
|
|
4
4
|
exports.createTransport = createTransport;
|
|
5
5
|
const identity_js_1 = require("./identity.js");
|
|
6
6
|
const protocol_js_1 = require("./protocol.js");
|
|
7
|
+
const errors_js_1 = require("./errors.js");
|
|
7
8
|
/**
|
|
8
9
|
* HTTP transport for EHBP
|
|
9
10
|
*/
|
|
@@ -34,6 +35,29 @@ class Transport {
|
|
|
34
35
|
const serverIdentity = await identity_js_1.Identity.unmarshalPublicConfig(keysData);
|
|
35
36
|
return new Transport(serverIdentity, serverHost);
|
|
36
37
|
}
|
|
38
|
+
static isProblemJSONContentType(contentType) {
|
|
39
|
+
if (!contentType) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const mediaType = contentType.split(';', 1)[0]?.trim().toLowerCase() ?? '';
|
|
43
|
+
return mediaType === protocol_js_1.PROTOCOL.PROBLEM_JSON_MEDIA_TYPE;
|
|
44
|
+
}
|
|
45
|
+
static async checkKeyConfigMismatch(response) {
|
|
46
|
+
if (response.status !== 422)
|
|
47
|
+
return;
|
|
48
|
+
if (!Transport.isProblemJSONContentType(response.headers.get('content-type')))
|
|
49
|
+
return;
|
|
50
|
+
let problem;
|
|
51
|
+
try {
|
|
52
|
+
problem = (await response.clone().json());
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return; // Not valid JSON — not a key config mismatch
|
|
56
|
+
}
|
|
57
|
+
if (problem?.type === protocol_js_1.PROTOCOL.KEY_CONFIG_PROBLEM_TYPE) {
|
|
58
|
+
throw new errors_js_1.KeyConfigMismatchError(typeof problem.title === 'string' ? problem.title : undefined);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
37
61
|
/**
|
|
38
62
|
* Get the server identity
|
|
39
63
|
*/
|
|
@@ -88,7 +112,7 @@ class Transport {
|
|
|
88
112
|
headers = init?.headers || {};
|
|
89
113
|
}
|
|
90
114
|
url.host = this.serverHost;
|
|
91
|
-
|
|
115
|
+
const request = new Request(url.toString(), {
|
|
92
116
|
method,
|
|
93
117
|
headers,
|
|
94
118
|
body: requestBody,
|
|
@@ -99,17 +123,16 @@ class Transport {
|
|
|
99
123
|
const { request: encryptedRequest, context } = await this.serverIdentity.encryptRequestWithContext(request);
|
|
100
124
|
// Make the request
|
|
101
125
|
const response = await fetch(encryptedRequest);
|
|
102
|
-
if (!response.ok) {
|
|
103
|
-
console.warn(`Server returned non-OK status: ${response.status}`);
|
|
104
|
-
}
|
|
105
126
|
// Bodyless requests: context is null, response is plaintext
|
|
106
127
|
if (context === null) {
|
|
107
128
|
return response;
|
|
108
129
|
}
|
|
130
|
+
// Throws KeyConfigMismatchError if server returned 422 key-config mismatch
|
|
131
|
+
await Transport.checkKeyConfigMismatch(response);
|
|
109
132
|
// Check for response nonce header (required for response decryption)
|
|
110
133
|
const responseNonceHeader = response.headers.get(protocol_js_1.PROTOCOL.RESPONSE_NONCE_HEADER);
|
|
111
134
|
if (!responseNonceHeader) {
|
|
112
|
-
throw new
|
|
135
|
+
throw new errors_js_1.ProtocolError(`Missing ${protocol_js_1.PROTOCOL.RESPONSE_NONCE_HEADER} header`);
|
|
113
136
|
}
|
|
114
137
|
// Decrypt response
|
|
115
138
|
return await this.serverIdentity.decryptResponseWithContext(response, context);
|
package/dist/cjs/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/derive.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../../src/derive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../../src/derive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAC5C,eAAO,MAAM,aAAa,KAAK,CAAC;AAChC,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAMrC;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,QAAQ,EAAE,UAAU,CAAC;IACrB,0DAA0D;IAC1D,SAAS,EAAE,UAAU,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CACtC,cAAc,EAAE,UAAU,EAC1B,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,UAAU,GACxB,OAAO,CAAC,mBAAmB,CAAC,CA2B9B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAyB3E;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,mBAAmB,EACvB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC,UAAU,CAAC,CAMrB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,mBAAmB,EACvB,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,UAAU,CAAC,CAMrB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAYlD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIpD"}
|
package/dist/cjs/derive.js
CHANGED
|
@@ -18,9 +18,9 @@ exports.encryptChunk = encryptChunk;
|
|
|
18
18
|
exports.decryptChunk = decryptChunk;
|
|
19
19
|
exports.hexToBytes = hexToBytes;
|
|
20
20
|
exports.bytesToHex = bytesToHex;
|
|
21
|
-
const
|
|
22
|
-
const kdf = (0,
|
|
23
|
-
const aead = (0,
|
|
21
|
+
const hpke_noble_1 = require("@panva/hpke-noble");
|
|
22
|
+
const kdf = (0, hpke_noble_1.KDF_HKDF_SHA256)();
|
|
23
|
+
const aead = (0, hpke_noble_1.AEAD_AES_256_GCM)();
|
|
24
24
|
exports.HPKE_REQUEST_INFO = 'ehbp request';
|
|
25
25
|
exports.EXPORT_LABEL = 'ehbp response';
|
|
26
26
|
exports.EXPORT_LENGTH = 32;
|
package/dist/cjs/derive.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive.js","sourceRoot":"","sources":["../../src/derive.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;
|
|
1
|
+
{"version":3,"file":"derive.js","sourceRoot":"","sources":["../../src/derive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EHBP error hierarchy:
|
|
3
|
+
*
|
|
4
|
+
* EhbpError (base)
|
|
5
|
+
* ├── KeyConfigMismatchError - 422 key-config mismatch (stale key after rotation)
|
|
6
|
+
* ├── ProtocolError - Malformed framing or crypto setup failure
|
|
7
|
+
* └── DecryptionError - AEAD authentication / decryption failure
|
|
8
|
+
*/
|
|
9
|
+
export declare class EhbpError extends Error {
|
|
10
|
+
constructor(message: string, options?: {
|
|
11
|
+
cause?: unknown;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Server returned 422 with problem+json key-config mismatch.
|
|
16
|
+
* The request was never processed — re-sending after re-keying is safe.
|
|
17
|
+
*/
|
|
18
|
+
export declare class KeyConfigMismatchError extends EhbpError {
|
|
19
|
+
readonly title: string;
|
|
20
|
+
constructor(title?: string);
|
|
21
|
+
}
|
|
22
|
+
export declare class ProtocolError extends EhbpError {
|
|
23
|
+
constructor(message: string, options?: {
|
|
24
|
+
cause?: unknown;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export declare class DecryptionError extends EhbpError {
|
|
28
|
+
constructor(message: string, options?: {
|
|
29
|
+
cause?: unknown;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAK3D;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,SAAS;IACnD,SAAgB,KAAK,EAAE,MAAM,CAAC;gBAClB,KAAK,CAAC,EAAE,MAAM;CAK3B;AAED,qBAAa,aAAc,SAAQ,SAAS;gBAC9B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D;AAED,qBAAa,eAAgB,SAAQ,SAAS;gBAChC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* EHBP error hierarchy:
|
|
4
|
+
*
|
|
5
|
+
* EhbpError (base)
|
|
6
|
+
* ├── KeyConfigMismatchError - 422 key-config mismatch (stale key after rotation)
|
|
7
|
+
* ├── ProtocolError - Malformed framing or crypto setup failure
|
|
8
|
+
* └── DecryptionError - AEAD authentication / decryption failure
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.DecryptionError = exports.ProtocolError = exports.KeyConfigMismatchError = exports.EhbpError = void 0;
|
|
12
|
+
class EhbpError extends Error {
|
|
13
|
+
constructor(message, options) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = 'EhbpError';
|
|
16
|
+
if (options?.cause)
|
|
17
|
+
this.cause = options.cause;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.EhbpError = EhbpError;
|
|
21
|
+
/**
|
|
22
|
+
* Server returned 422 with problem+json key-config mismatch.
|
|
23
|
+
* The request was never processed — re-sending after re-keying is safe.
|
|
24
|
+
*/
|
|
25
|
+
class KeyConfigMismatchError extends EhbpError {
|
|
26
|
+
title;
|
|
27
|
+
constructor(title) {
|
|
28
|
+
super(title || 'Server key configuration mismatch');
|
|
29
|
+
this.name = 'KeyConfigMismatchError';
|
|
30
|
+
this.title = title || '';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.KeyConfigMismatchError = KeyConfigMismatchError;
|
|
34
|
+
class ProtocolError extends EhbpError {
|
|
35
|
+
constructor(message, options) {
|
|
36
|
+
super(message, options);
|
|
37
|
+
this.name = 'ProtocolError';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.ProtocolError = ProtocolError;
|
|
41
|
+
class DecryptionError extends EhbpError {
|
|
42
|
+
constructor(message, options) {
|
|
43
|
+
super(message, options);
|
|
44
|
+
this.name = 'DecryptionError';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.DecryptionError = DecryptionError;
|
|
48
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,MAAa,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,OAAO,EAAE,KAAK;YAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IACjD,CAAC;CACF;AAND,8BAMC;AAED;;;GAGG;AACH,MAAa,sBAAuB,SAAQ,SAAS;IACnC,KAAK,CAAS;IAC9B,YAAY,KAAc;QACxB,KAAK,CAAC,KAAK,IAAI,mCAAmC,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC;IAC3B,CAAC;CACF;AAPD,wDAOC;AAED,MAAa,aAAc,SAAQ,SAAS;IAC1C,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AALD,sCAKC;AAED,MAAa,eAAgB,SAAQ,SAAS;IAC5C,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AALD,0CAKC"}
|
package/dist/cjs/identity.d.ts
CHANGED
|
@@ -56,6 +56,15 @@ export declare class Identity {
|
|
|
56
56
|
* and don't need to fetch it.
|
|
57
57
|
*/
|
|
58
58
|
static fromPublicKeyHex(publicKeyHex: string): Promise<Identity>;
|
|
59
|
+
/**
|
|
60
|
+
* Create an Identity from raw public key bytes.
|
|
61
|
+
* Uses the default cipher suite (X25519/HKDF-SHA256/AES-256-GCM).
|
|
62
|
+
*
|
|
63
|
+
* For public-key-only identities (client-side use), we create a placeholder
|
|
64
|
+
* private key that won't be used. TODO: refactor Identity to not require
|
|
65
|
+
* a private key for client-side use.
|
|
66
|
+
*/
|
|
67
|
+
private static fromPublicKeyBytes;
|
|
59
68
|
/**
|
|
60
69
|
* Encrypt request body and return context for response decryption.
|
|
61
70
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAgBjE;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,EAAE,UAAU,CAAC;CACxB;AAaD;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,UAAU,CAAM;gBAEZ,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG;IAM/D;;OAEG;WACU,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IAO1C;;OAEG;WACU,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAWtD;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAU/B;;OAEG;IACH,YAAY,IAAI,GAAG;IAInB;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;IAKxC;;OAEG;IACH,aAAa,IAAI,GAAG;IAIpB;;;OAGG;IACG,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC;IA0C1C;;OAEG;WACU,qBAAqB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC;IA2CvE;;;;;;OAMG;WACU,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAStE;;;;;;;OAOG;mBACkB,kBAAkB;IAQvC;;;;;;;;OAQG;IACG,yBAAyB,CAC7B,OAAO,EAAE,OAAO,GACf,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAA;KAAE,CAAC;IAwDhE;;;;;;;;OAQG;IACG,0BAA0B,CAC9B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,QAAQ,CAAC;IAmCpB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CA4D5B"}
|
package/dist/cjs/identity.js
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Identity = void 0;
|
|
4
4
|
const hpke_1 = require("hpke");
|
|
5
|
+
const hpke_noble_1 = require("@panva/hpke-noble");
|
|
5
6
|
const protocol_js_1 = require("./protocol.js");
|
|
6
7
|
const derive_js_1 = require("./derive.js");
|
|
8
|
+
const errors_js_1 = require("./errors.js");
|
|
7
9
|
/**
|
|
8
10
|
* Creates a new CipherSuite for X25519/HKDF-SHA256/AES-256-GCM
|
|
9
11
|
*/
|
|
10
12
|
function createSuite() {
|
|
11
|
-
return new hpke_1.CipherSuite(
|
|
13
|
+
return new hpke_1.CipherSuite(hpke_noble_1.KEM_DHKEM_X25519_HKDF_SHA256, hpke_noble_1.KDF_HKDF_SHA256, hpke_noble_1.AEAD_AES_256_GCM);
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
14
16
|
* Identity class for managing HPKE key pairs and encryption/decryption
|
|
@@ -130,22 +132,15 @@ class Identity {
|
|
|
130
132
|
suites.push({ kdfId, aeadId });
|
|
131
133
|
}
|
|
132
134
|
if (suites.length === 0) {
|
|
133
|
-
throw new
|
|
135
|
+
throw new errors_js_1.ProtocolError('No cipher suites found in config');
|
|
134
136
|
}
|
|
135
137
|
// Use the first cipher suite
|
|
136
138
|
const firstSuite = suites[0];
|
|
137
139
|
// Validate that we support this cipher suite
|
|
138
140
|
if (firstSuite.kdfId !== protocol_js_1.HPKE_CONFIG.KDF || firstSuite.aeadId !== protocol_js_1.HPKE_CONFIG.AEAD) {
|
|
139
|
-
throw new
|
|
141
|
+
throw new errors_js_1.ProtocolError(`Unsupported cipher suite: KDF=0x${firstSuite.kdfId.toString(16)}, AEAD=0x${firstSuite.aeadId.toString(16)}`);
|
|
140
142
|
}
|
|
141
|
-
|
|
142
|
-
const suite = createSuite();
|
|
143
|
-
// Import public key
|
|
144
|
-
const publicKey = await suite.DeserializePublicKey(publicKeyBytes);
|
|
145
|
-
// For server config, we only have the public key, no private key
|
|
146
|
-
// We'll create a dummy private key that won't be used
|
|
147
|
-
const dummyPrivateKey = await suite.DeserializePrivateKey(new Uint8Array(32), false);
|
|
148
|
-
return new Identity(suite, publicKey, dummyPrivateKey);
|
|
143
|
+
return Identity.fromPublicKeyBytes(publicKeyBytes);
|
|
149
144
|
}
|
|
150
145
|
/**
|
|
151
146
|
* Create an Identity from a raw public key hex string.
|
|
@@ -157,16 +152,23 @@ class Identity {
|
|
|
157
152
|
static async fromPublicKeyHex(publicKeyHex) {
|
|
158
153
|
const publicKeyBytes = (0, derive_js_1.hexToBytes)(publicKeyHex);
|
|
159
154
|
if (publicKeyBytes.length !== 32) {
|
|
160
|
-
throw new
|
|
155
|
+
throw new errors_js_1.ProtocolError(`Invalid public key length: expected 32, got ${publicKeyBytes.length}`);
|
|
161
156
|
}
|
|
157
|
+
return Identity.fromPublicKeyBytes(publicKeyBytes);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Create an Identity from raw public key bytes.
|
|
161
|
+
* Uses the default cipher suite (X25519/HKDF-SHA256/AES-256-GCM).
|
|
162
|
+
*
|
|
163
|
+
* For public-key-only identities (client-side use), we create a placeholder
|
|
164
|
+
* private key that won't be used. TODO: refactor Identity to not require
|
|
165
|
+
* a private key for client-side use.
|
|
166
|
+
*/
|
|
167
|
+
static async fromPublicKeyBytes(publicKeyBytes) {
|
|
162
168
|
const suite = createSuite();
|
|
163
169
|
const publicKey = await suite.DeserializePublicKey(publicKeyBytes);
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
// TODO: maybe refactor Identity to not require a private key for
|
|
167
|
-
// client-side use?
|
|
168
|
-
const dummyPrivateKey = await suite.DeserializePrivateKey(new Uint8Array(32), false);
|
|
169
|
-
return new Identity(suite, publicKey, dummyPrivateKey);
|
|
170
|
+
const placeholderPrivateKey = await suite.DeserializePrivateKey(new Uint8Array(32), false);
|
|
171
|
+
return new Identity(suite, publicKey, placeholderPrivateKey);
|
|
170
172
|
}
|
|
171
173
|
/**
|
|
172
174
|
* Encrypt request body and return context for response decryption.
|
|
@@ -240,11 +242,11 @@ class Identity {
|
|
|
240
242
|
// Get response nonce from header
|
|
241
243
|
const responseNonceHex = response.headers.get(protocol_js_1.PROTOCOL.RESPONSE_NONCE_HEADER);
|
|
242
244
|
if (!responseNonceHex) {
|
|
243
|
-
throw new
|
|
245
|
+
throw new errors_js_1.ProtocolError(`Missing ${protocol_js_1.PROTOCOL.RESPONSE_NONCE_HEADER} header`);
|
|
244
246
|
}
|
|
245
247
|
const responseNonce = (0, derive_js_1.hexToBytes)(responseNonceHex);
|
|
246
248
|
if (responseNonce.length !== derive_js_1.RESPONSE_NONCE_LENGTH) {
|
|
247
|
-
throw new
|
|
249
|
+
throw new errors_js_1.ProtocolError(`Invalid response nonce length: expected ${derive_js_1.RESPONSE_NONCE_LENGTH}, got ${responseNonce.length}`);
|
|
248
250
|
}
|
|
249
251
|
// Export secret from request context
|
|
250
252
|
const exportLabelBytes = new TextEncoder().encode(derive_js_1.EXPORT_LABEL);
|
|
@@ -286,7 +288,7 @@ class Identity {
|
|
|
286
288
|
return;
|
|
287
289
|
}
|
|
288
290
|
catch (error) {
|
|
289
|
-
controller.error(new
|
|
291
|
+
controller.error(new errors_js_1.DecryptionError(`Decryption failed at chunk ${seq - 1}`, { cause: error }));
|
|
290
292
|
return;
|
|
291
293
|
}
|
|
292
294
|
}
|
package/dist/cjs/identity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":";;;AAAA,+
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export { Identity } from './identity.js';
|
|
|
9
9
|
export type { RequestContext } from './identity.js';
|
|
10
10
|
export { Transport, createTransport } from './client.js';
|
|
11
11
|
export { PROTOCOL, HPKE_CONFIG } from './protocol.js';
|
|
12
|
+
export { EhbpError, KeyConfigMismatchError, ProtocolError, DecryptionError, } from './errors.js';
|
|
12
13
|
export { deriveResponseKeys, computeNonce, encryptChunk, decryptChunk, hexToBytes, bytesToHex, HPKE_REQUEST_INFO, EXPORT_LABEL, EXPORT_LENGTH, RESPONSE_NONCE_LENGTH, AES256_KEY_LENGTH, AES_GCM_NONCE_LENGTH, } from './derive.js';
|
|
13
14
|
export type { ResponseKeyMaterial } from './derive.js';
|
|
14
15
|
export type { CipherSuite, SenderContext, RecipientContext, Key } from 'hpke';
|
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACL,SAAS,EACT,sBAAsB,EACtB,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* bodies while preserving HTTP headers for routing.
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.AES_GCM_NONCE_LENGTH = exports.AES256_KEY_LENGTH = exports.RESPONSE_NONCE_LENGTH = exports.EXPORT_LENGTH = exports.EXPORT_LABEL = exports.HPKE_REQUEST_INFO = exports.bytesToHex = exports.hexToBytes = exports.decryptChunk = exports.encryptChunk = exports.computeNonce = exports.deriveResponseKeys = exports.HPKE_CONFIG = exports.PROTOCOL = exports.createTransport = exports.Transport = exports.Identity = void 0;
|
|
10
|
+
exports.AES_GCM_NONCE_LENGTH = exports.AES256_KEY_LENGTH = exports.RESPONSE_NONCE_LENGTH = exports.EXPORT_LENGTH = exports.EXPORT_LABEL = exports.HPKE_REQUEST_INFO = exports.bytesToHex = exports.hexToBytes = exports.decryptChunk = exports.encryptChunk = exports.computeNonce = exports.deriveResponseKeys = exports.DecryptionError = exports.ProtocolError = exports.KeyConfigMismatchError = exports.EhbpError = exports.HPKE_CONFIG = exports.PROTOCOL = exports.createTransport = exports.Transport = exports.Identity = void 0;
|
|
11
11
|
var identity_js_1 = require("./identity.js");
|
|
12
12
|
Object.defineProperty(exports, "Identity", { enumerable: true, get: function () { return identity_js_1.Identity; } });
|
|
13
13
|
var client_js_1 = require("./client.js");
|
|
@@ -16,6 +16,11 @@ Object.defineProperty(exports, "createTransport", { enumerable: true, get: funct
|
|
|
16
16
|
var protocol_js_1 = require("./protocol.js");
|
|
17
17
|
Object.defineProperty(exports, "PROTOCOL", { enumerable: true, get: function () { return protocol_js_1.PROTOCOL; } });
|
|
18
18
|
Object.defineProperty(exports, "HPKE_CONFIG", { enumerable: true, get: function () { return protocol_js_1.HPKE_CONFIG; } });
|
|
19
|
+
var errors_js_1 = require("./errors.js");
|
|
20
|
+
Object.defineProperty(exports, "EhbpError", { enumerable: true, get: function () { return errors_js_1.EhbpError; } });
|
|
21
|
+
Object.defineProperty(exports, "KeyConfigMismatchError", { enumerable: true, get: function () { return errors_js_1.KeyConfigMismatchError; } });
|
|
22
|
+
Object.defineProperty(exports, "ProtocolError", { enumerable: true, get: function () { return errors_js_1.ProtocolError; } });
|
|
23
|
+
Object.defineProperty(exports, "DecryptionError", { enumerable: true, get: function () { return errors_js_1.DecryptionError; } });
|
|
19
24
|
// Export key derivation utilities for advanced usage
|
|
20
25
|
var derive_js_1 = require("./derive.js");
|
|
21
26
|
Object.defineProperty(exports, "deriveResponseKeys", { enumerable: true, get: function () { return derive_js_1.deriveResponseKeys; } });
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;AAEjB,yCAAyD;AAAhD,sGAAA,SAAS,OAAA;AAAE,4GAAA,eAAe,OAAA;AACnC,6CAAsD;AAA7C,uGAAA,QAAQ,OAAA;AAAE,0GAAA,WAAW,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;AAEjB,yCAAyD;AAAhD,sGAAA,SAAS,OAAA;AAAE,4GAAA,eAAe,OAAA;AACnC,6CAAsD;AAA7C,uGAAA,QAAQ,OAAA;AAAE,0GAAA,WAAW,OAAA;AAC9B,yCAKqB;AAJnB,sGAAA,SAAS,OAAA;AACT,mHAAA,sBAAsB,OAAA;AACtB,0GAAA,aAAa,OAAA;AACb,4GAAA,eAAe,OAAA;AAGjB,qDAAqD;AACrD,yCAaqB;AAZnB,+GAAA,kBAAkB,OAAA;AAClB,yGAAA,YAAY,OAAA;AACZ,yGAAA,YAAY,OAAA;AACZ,yGAAA,YAAY,OAAA;AACZ,uGAAA,UAAU,OAAA;AACV,uGAAA,UAAU,OAAA;AACV,8GAAA,iBAAiB,OAAA;AACjB,yGAAA,YAAY,OAAA;AACZ,0GAAA,aAAa,OAAA;AACb,kHAAA,qBAAqB,OAAA;AACrB,8GAAA,iBAAiB,OAAA;AACjB,iHAAA,oBAAoB,OAAA"}
|
package/dist/cjs/protocol.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export declare const PROTOCOL: {
|
|
|
6
6
|
readonly RESPONSE_NONCE_HEADER: "Ehbp-Response-Nonce";
|
|
7
7
|
readonly KEYS_MEDIA_TYPE: "application/ohttp-keys";
|
|
8
8
|
readonly KEYS_PATH: "/.well-known/hpke-keys";
|
|
9
|
+
readonly PROBLEM_JSON_MEDIA_TYPE: "application/problem+json";
|
|
10
|
+
readonly KEY_CONFIG_PROBLEM_TYPE: "urn:ietf:params:ehbp:error:key-config";
|
|
9
11
|
};
|
|
10
12
|
/**
|
|
11
13
|
* HPKE suite configuration matching the Go implementation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,QAAQ
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;;;CAOX,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,WAAW;;;;CAId,CAAC"}
|
package/dist/cjs/protocol.js
CHANGED
|
@@ -9,6 +9,8 @@ exports.PROTOCOL = {
|
|
|
9
9
|
RESPONSE_NONCE_HEADER: 'Ehbp-Response-Nonce',
|
|
10
10
|
KEYS_MEDIA_TYPE: 'application/ohttp-keys',
|
|
11
11
|
KEYS_PATH: '/.well-known/hpke-keys',
|
|
12
|
+
PROBLEM_JSON_MEDIA_TYPE: 'application/problem+json',
|
|
13
|
+
KEY_CONFIG_PROBLEM_TYPE: 'urn:ietf:params:ehbp:error:key-config',
|
|
12
14
|
};
|
|
13
15
|
/**
|
|
14
16
|
* HPKE suite configuration matching the Go implementation
|
package/dist/cjs/protocol.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,QAAQ,GAAG;IACtB,uBAAuB,EAAE,uBAAuB;IAChD,qBAAqB,EAAE,qBAAqB;IAC5C,eAAe,EAAE,wBAAwB;IACzC,SAAS,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,QAAQ,GAAG;IACtB,uBAAuB,EAAE,uBAAuB;IAChD,qBAAqB,EAAE,qBAAqB;IAC5C,eAAe,EAAE,wBAAwB;IACzC,SAAS,EAAE,wBAAwB;IACnC,uBAAuB,EAAE,0BAA0B;IACnD,uBAAuB,EAAE,uCAAuC;CACxD,CAAC;AAEX;;GAEG;AACU,QAAA,WAAW,GAAG;IACzB,GAAG,EAAE,MAAM,EAAE,qBAAqB;IAClC,GAAG,EAAE,MAAM,EAAE,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC,cAAc;CACnB,CAAC"}
|
package/dist/esm/client.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export declare class Transport {
|
|
|
11
11
|
* Create a new transport by fetching server public key.
|
|
12
12
|
*/
|
|
13
13
|
static create(serverURL: string): Promise<Transport>;
|
|
14
|
+
private static isProblemJSONContentType;
|
|
15
|
+
private static checkKeyConfigMismatch;
|
|
14
16
|
/**
|
|
15
17
|
* Get the server identity
|
|
16
18
|
*/
|
package/dist/esm/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAOhC;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,cAAc,CAAW;IACjC,OAAO,CAAC,UAAU,CAAS;gBAEf,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM;IAKxD;;OAEG;WACU,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAuB1D,OAAO,CAAC,MAAM,CAAC,wBAAwB;mBAQlB,sBAAsB;IAiB3C;;OAEG;IACH,iBAAiB,IAAI,QAAQ;IAI7B;;OAEG;IACH,kBAAkB,IAAI,GAAG;IAIzB;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAI9C;;OAEG;IACG,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAsE9E;;OAEG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAInE;;OAEG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIrF;;OAEG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIpF;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;CAGvE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAE3E"}
|
package/dist/esm/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Identity } from './identity.js';
|
|
2
2
|
import { PROTOCOL } from './protocol.js';
|
|
3
|
+
import { KeyConfigMismatchError, ProtocolError } from './errors.js';
|
|
3
4
|
/**
|
|
4
5
|
* HTTP transport for EHBP
|
|
5
6
|
*/
|
|
@@ -30,6 +31,29 @@ export class Transport {
|
|
|
30
31
|
const serverIdentity = await Identity.unmarshalPublicConfig(keysData);
|
|
31
32
|
return new Transport(serverIdentity, serverHost);
|
|
32
33
|
}
|
|
34
|
+
static isProblemJSONContentType(contentType) {
|
|
35
|
+
if (!contentType) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const mediaType = contentType.split(';', 1)[0]?.trim().toLowerCase() ?? '';
|
|
39
|
+
return mediaType === PROTOCOL.PROBLEM_JSON_MEDIA_TYPE;
|
|
40
|
+
}
|
|
41
|
+
static async checkKeyConfigMismatch(response) {
|
|
42
|
+
if (response.status !== 422)
|
|
43
|
+
return;
|
|
44
|
+
if (!Transport.isProblemJSONContentType(response.headers.get('content-type')))
|
|
45
|
+
return;
|
|
46
|
+
let problem;
|
|
47
|
+
try {
|
|
48
|
+
problem = (await response.clone().json());
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return; // Not valid JSON — not a key config mismatch
|
|
52
|
+
}
|
|
53
|
+
if (problem?.type === PROTOCOL.KEY_CONFIG_PROBLEM_TYPE) {
|
|
54
|
+
throw new KeyConfigMismatchError(typeof problem.title === 'string' ? problem.title : undefined);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
33
57
|
/**
|
|
34
58
|
* Get the server identity
|
|
35
59
|
*/
|
|
@@ -84,7 +108,7 @@ export class Transport {
|
|
|
84
108
|
headers = init?.headers || {};
|
|
85
109
|
}
|
|
86
110
|
url.host = this.serverHost;
|
|
87
|
-
|
|
111
|
+
const request = new Request(url.toString(), {
|
|
88
112
|
method,
|
|
89
113
|
headers,
|
|
90
114
|
body: requestBody,
|
|
@@ -95,17 +119,16 @@ export class Transport {
|
|
|
95
119
|
const { request: encryptedRequest, context } = await this.serverIdentity.encryptRequestWithContext(request);
|
|
96
120
|
// Make the request
|
|
97
121
|
const response = await fetch(encryptedRequest);
|
|
98
|
-
if (!response.ok) {
|
|
99
|
-
console.warn(`Server returned non-OK status: ${response.status}`);
|
|
100
|
-
}
|
|
101
122
|
// Bodyless requests: context is null, response is plaintext
|
|
102
123
|
if (context === null) {
|
|
103
124
|
return response;
|
|
104
125
|
}
|
|
126
|
+
// Throws KeyConfigMismatchError if server returned 422 key-config mismatch
|
|
127
|
+
await Transport.checkKeyConfigMismatch(response);
|
|
105
128
|
// Check for response nonce header (required for response decryption)
|
|
106
129
|
const responseNonceHeader = response.headers.get(PROTOCOL.RESPONSE_NONCE_HEADER);
|
|
107
130
|
if (!responseNonceHeader) {
|
|
108
|
-
throw new
|
|
131
|
+
throw new ProtocolError(`Missing ${PROTOCOL.RESPONSE_NONCE_HEADER} header`);
|
|
109
132
|
}
|
|
110
133
|
// Decrypt response
|
|
111
134
|
return await this.serverIdentity.decryptResponseWithContext(response, context);
|