ehbp 0.1.7 → 0.2.1

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.
@@ -0,0 +1,460 @@
1
+ /**
2
+ * Session Recovery Token Tests
3
+ *
4
+ * These tests verify that extractSessionRecoveryToken and decryptResponseWithToken
5
+ * produce correct results by running real HPKE key exchanges and AES-256-GCM
6
+ * encryption/decryption — no mocks on the crypto path.
7
+ */
8
+ import { describe, it } from 'node:test';
9
+ import assert from 'node:assert';
10
+ import { readFileSync } from 'node:fs';
11
+ import { resolve, dirname } from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
13
+ import { Identity, extractSessionRecoveryToken, decryptResponseWithToken, serializeSessionRecoveryToken, deserializeSessionRecoveryToken, } from '../index.js';
14
+ import { PROTOCOL } from '../protocol.js';
15
+ import { CipherSuite, KEM_DHKEM_X25519_HKDF_SHA256, KDF_HKDF_SHA256, AEAD_AES_256_GCM, } from 'hpke';
16
+ import { bytesToHex, decryptChunk, deriveResponseKeys, encryptChunk, hexToBytes, EXPORT_LABEL, EXPORT_LENGTH, HPKE_REQUEST_INFO, RESPONSE_NONCE_LENGTH, } from '../derive.js';
17
+ // Shared suite — all key generation and SetupRecipient use this instance so
18
+ // CryptoKey objects are never passed across CipherSuite instances.
19
+ const suite = new CipherSuite(KEM_DHKEM_X25519_HKDF_SHA256, KDF_HKDF_SHA256, AEAD_AES_256_GCM);
20
+ const infoBytes = new TextEncoder().encode(HPKE_REQUEST_INFO);
21
+ const exportLabelBytes = new TextEncoder().encode(EXPORT_LABEL);
22
+ /**
23
+ * Generate a key pair from the shared suite and return a public-key-only
24
+ * Identity (for encryptRequestWithContext) plus the raw private key (for
25
+ * server-side simulation via SetupRecipient on the same suite).
26
+ */
27
+ async function generateTestKeys() {
28
+ const { publicKey, privateKey } = await suite.GenerateKeyPair(true);
29
+ const pubKeyBytes = new Uint8Array(await suite.SerializePublicKey(publicKey));
30
+ const identity = await Identity.fromPublicKeyHex(bytesToHex(pubKeyBytes));
31
+ return { identity, privateKey };
32
+ }
33
+ function encodeSingleChunk(payload) {
34
+ const chunkLength = new Uint8Array(4);
35
+ new DataView(chunkLength.buffer).setUint32(0, payload.byteLength, false);
36
+ const body = new Uint8Array(4 + payload.byteLength);
37
+ body.set(chunkLength, 0);
38
+ body.set(payload, 4);
39
+ return body;
40
+ }
41
+ function encodeMultipleChunks(payloads) {
42
+ let totalLength = 0;
43
+ for (const p of payloads)
44
+ totalLength += 4 + p.byteLength;
45
+ const body = new Uint8Array(totalLength);
46
+ let offset = 0;
47
+ for (const p of payloads) {
48
+ new DataView(body.buffer, offset, 4).setUint32(0, p.byteLength, false);
49
+ offset += 4;
50
+ body.set(p, offset);
51
+ offset += p.byteLength;
52
+ }
53
+ return body;
54
+ }
55
+ function toArrayBuffer(bytes) {
56
+ const copy = new Uint8Array(bytes.byteLength);
57
+ copy.set(bytes);
58
+ return copy.buffer;
59
+ }
60
+ /**
61
+ * Simulates what the server does: receives the encrypted request,
62
+ * decrypts it, then builds an encrypted response using the HPKE
63
+ * receiver context (matching the real protocol).
64
+ */
65
+ async function buildEncryptedResponse(request, privateKey, responseText) {
66
+ const requestEncHex = request.headers.get(PROTOCOL.ENCAPSULATED_KEY_HEADER);
67
+ assert(requestEncHex, `Missing ${PROTOCOL.ENCAPSULATED_KEY_HEADER} header`);
68
+ const requestEnc = hexToBytes(requestEncHex);
69
+ const recipientContext = await suite.SetupRecipient(privateKey, requestEnc, { info: infoBytes });
70
+ // Decrypt the request body to prove the HPKE handshake works
71
+ const encryptedBody = new Uint8Array(await request.arrayBuffer());
72
+ const chunkLen = new DataView(encryptedBody.buffer, encryptedBody.byteOffset, 4).getUint32(0, false);
73
+ const ciphertext = encryptedBody.slice(4, 4 + chunkLen);
74
+ await recipientContext.Open(ciphertext);
75
+ const responseNonce = new Uint8Array(RESPONSE_NONCE_LENGTH);
76
+ crypto.getRandomValues(responseNonce);
77
+ const exportedSecret = await recipientContext.Export(exportLabelBytes, EXPORT_LENGTH);
78
+ const keyMaterial = await deriveResponseKeys(exportedSecret, requestEnc, responseNonce);
79
+ const responseCiphertext = await encryptChunk(keyMaterial, 0, new TextEncoder().encode(responseText));
80
+ return new Response(toArrayBuffer(encodeSingleChunk(responseCiphertext)), {
81
+ status: 200,
82
+ headers: {
83
+ [PROTOCOL.RESPONSE_NONCE_HEADER]: bytesToHex(responseNonce),
84
+ },
85
+ });
86
+ }
87
+ /**
88
+ * Builds a multi-chunk encrypted streaming response (simulating SSE).
89
+ */
90
+ async function buildStreamingEncryptedResponse(request, privateKey, chunks) {
91
+ const requestEncHex = request.headers.get(PROTOCOL.ENCAPSULATED_KEY_HEADER);
92
+ assert(requestEncHex);
93
+ const requestEnc = hexToBytes(requestEncHex);
94
+ const recipientContext = await suite.SetupRecipient(privateKey, requestEnc, { info: infoBytes });
95
+ // Decrypt request to advance the HPKE context
96
+ const encryptedBody = new Uint8Array(await request.arrayBuffer());
97
+ const chunkLen = new DataView(encryptedBody.buffer, encryptedBody.byteOffset, 4).getUint32(0, false);
98
+ await recipientContext.Open(encryptedBody.slice(4, 4 + chunkLen));
99
+ const responseNonce = new Uint8Array(RESPONSE_NONCE_LENGTH);
100
+ crypto.getRandomValues(responseNonce);
101
+ const exportedSecret = await recipientContext.Export(exportLabelBytes, EXPORT_LENGTH);
102
+ const keyMaterial = await deriveResponseKeys(exportedSecret, requestEnc, responseNonce);
103
+ const encryptedChunks = [];
104
+ for (let i = 0; i < chunks.length; i++) {
105
+ encryptedChunks.push(await encryptChunk(keyMaterial, i, new TextEncoder().encode(chunks[i])));
106
+ }
107
+ return new Response(toArrayBuffer(encodeMultipleChunks(encryptedChunks)), {
108
+ status: 200,
109
+ headers: {
110
+ [PROTOCOL.RESPONSE_NONCE_HEADER]: bytesToHex(responseNonce),
111
+ },
112
+ });
113
+ }
114
+ describe('Session Recovery Token', () => {
115
+ describe('extractSessionRecoveryToken', () => {
116
+ it('should return a token with correct field sizes', async () => {
117
+ const { identity } = await generateTestKeys();
118
+ const request = new Request('https://server.test/api', {
119
+ method: 'POST',
120
+ body: 'test body',
121
+ });
122
+ const { context } = await identity.encryptRequestWithContext(request);
123
+ assert(context, 'context must not be null for a request with a body');
124
+ const token = await extractSessionRecoveryToken(context);
125
+ assert.strictEqual(token.exportedSecret.length, 32, 'exportedSecret must be 32 bytes');
126
+ assert.strictEqual(token.requestEnc.length, 32, 'requestEnc must be 32 bytes');
127
+ });
128
+ it('should return the same exported secret as SenderContext.Export', async () => {
129
+ const { identity } = await generateTestKeys();
130
+ const request = new Request('https://server.test/api', {
131
+ method: 'POST',
132
+ body: 'test body',
133
+ });
134
+ const { context } = await identity.encryptRequestWithContext(request);
135
+ assert(context);
136
+ // Export directly from the SenderContext for comparison
137
+ const directExport = new Uint8Array(await context.senderContext.Export(exportLabelBytes, EXPORT_LENGTH));
138
+ const token = await extractSessionRecoveryToken(context);
139
+ assert.deepStrictEqual(token.exportedSecret, directExport, 'Token exportedSecret must match direct SenderContext.Export result');
140
+ });
141
+ it('should return requestEnc matching the context', async () => {
142
+ const { identity } = await generateTestKeys();
143
+ const request = new Request('https://server.test/api', {
144
+ method: 'POST',
145
+ body: 'test body',
146
+ });
147
+ const { context } = await identity.encryptRequestWithContext(request);
148
+ assert(context);
149
+ const token = await extractSessionRecoveryToken(context);
150
+ assert.deepStrictEqual(token.requestEnc, context.requestEnc, 'Token requestEnc must match context.requestEnc');
151
+ });
152
+ it('should produce different tokens for different requests', async () => {
153
+ const { identity } = await generateTestKeys();
154
+ const req1 = new Request('https://server.test/api', { method: 'POST', body: 'request 1' });
155
+ const req2 = new Request('https://server.test/api', { method: 'POST', body: 'request 2' });
156
+ const { context: ctx1 } = await identity.encryptRequestWithContext(req1);
157
+ const { context: ctx2 } = await identity.encryptRequestWithContext(req2);
158
+ assert(ctx1 && ctx2);
159
+ const token1 = await extractSessionRecoveryToken(ctx1);
160
+ const token2 = await extractSessionRecoveryToken(ctx2);
161
+ // Each request creates a fresh HPKE context, so exported secrets differ
162
+ assert.notDeepStrictEqual(token1.exportedSecret, token2.exportedSecret, 'Different requests must produce different exported secrets');
163
+ assert.notDeepStrictEqual(token1.requestEnc, token2.requestEnc, 'Different requests must produce different requestEnc values');
164
+ });
165
+ });
166
+ describe('decryptResponseWithToken', () => {
167
+ it('should decrypt a single-chunk response', async () => {
168
+ const { identity, privateKey } = await generateTestKeys();
169
+ const request = new Request('https://server.test/api', {
170
+ method: 'POST',
171
+ body: 'hello',
172
+ });
173
+ const { request: encryptedRequest, context } = await identity.encryptRequestWithContext(request);
174
+ assert(context);
175
+ const token = await extractSessionRecoveryToken(context);
176
+ // Server builds an encrypted response using the real HPKE handshake
177
+ const encryptedResponse = await buildEncryptedResponse(encryptedRequest, privateKey, 'response from server');
178
+ const decrypted = await decryptResponseWithToken(encryptedResponse, token);
179
+ const text = await decrypted.text();
180
+ assert.strictEqual(text, 'response from server');
181
+ });
182
+ it('should decrypt a multi-chunk streaming response', async () => {
183
+ const { identity, privateKey } = await generateTestKeys();
184
+ const request = new Request('https://server.test/api', {
185
+ method: 'POST',
186
+ body: 'hello',
187
+ });
188
+ const { request: encryptedRequest, context } = await identity.encryptRequestWithContext(request);
189
+ assert(context);
190
+ const token = await extractSessionRecoveryToken(context);
191
+ const chunks = ['chunk-0:', 'chunk-1:', 'chunk-2:done'];
192
+ const encryptedResponse = await buildStreamingEncryptedResponse(encryptedRequest, privateKey, chunks);
193
+ const decrypted = await decryptResponseWithToken(encryptedResponse, token);
194
+ const text = await decrypted.text();
195
+ assert.strictEqual(text, chunks.join(''));
196
+ });
197
+ it('should preserve response status and headers', async () => {
198
+ const { identity, privateKey } = await generateTestKeys();
199
+ const request = new Request('https://server.test/api', {
200
+ method: 'POST',
201
+ body: 'hello',
202
+ });
203
+ const { request: encryptedRequest, context } = await identity.encryptRequestWithContext(request);
204
+ assert(context);
205
+ const token = await extractSessionRecoveryToken(context);
206
+ const encryptedResponse = await buildEncryptedResponse(encryptedRequest, privateKey, 'ok');
207
+ const decrypted = await decryptResponseWithToken(encryptedResponse, token);
208
+ assert.strictEqual(decrypted.status, 200);
209
+ assert(decrypted.headers.has(PROTOCOL.RESPONSE_NONCE_HEADER));
210
+ });
211
+ it('should return the response as-is when body is null', async () => {
212
+ const token = {
213
+ exportedSecret: new Uint8Array(32),
214
+ requestEnc: new Uint8Array(32),
215
+ };
216
+ const response = new Response(null, { status: 204 });
217
+ const result = await decryptResponseWithToken(response, token);
218
+ assert.strictEqual(result.status, 204);
219
+ assert.strictEqual(result.body, null);
220
+ });
221
+ it('should throw on missing response nonce header', async () => {
222
+ const token = {
223
+ exportedSecret: new Uint8Array(32),
224
+ requestEnc: new Uint8Array(32),
225
+ };
226
+ // Body present but no Ehbp-Response-Nonce header
227
+ const response = new Response('encrypted-data', { status: 200 });
228
+ await assert.rejects(() => decryptResponseWithToken(response, token), /Missing Ehbp-Response-Nonce header/);
229
+ });
230
+ it('should throw on invalid response nonce length', async () => {
231
+ const token = {
232
+ exportedSecret: new Uint8Array(32),
233
+ requestEnc: new Uint8Array(32),
234
+ };
235
+ // 12-byte nonce instead of required 32
236
+ const shortNonce = bytesToHex(new Uint8Array(12));
237
+ const response = new Response('encrypted-data', {
238
+ status: 200,
239
+ headers: { [PROTOCOL.RESPONSE_NONCE_HEADER]: shortNonce },
240
+ });
241
+ await assert.rejects(() => decryptResponseWithToken(response, token), /Invalid response nonce length/);
242
+ });
243
+ it('should reject a response chunk that exceeds the maximum size', async () => {
244
+ const token = {
245
+ exportedSecret: new Uint8Array(32),
246
+ requestEnc: new Uint8Array(32),
247
+ };
248
+ // Valid 32-byte nonce so key derivation proceeds, but the length prefix
249
+ // declares a ~4 GiB chunk that must be rejected before buffering the
250
+ // (unauthenticated) body.
251
+ const nonce = bytesToHex(new Uint8Array(RESPONSE_NONCE_LENGTH));
252
+ const body = new Uint8Array([0xff, 0xff, 0xff, 0xff, 0x00]);
253
+ const response = new Response(body, {
254
+ status: 200,
255
+ headers: { [PROTOCOL.RESPONSE_NONCE_HEADER]: nonce },
256
+ });
257
+ const decrypted = await decryptResponseWithToken(response, token);
258
+ await assert.rejects(() => decrypted.text(), /maximum allowed size/);
259
+ });
260
+ it('should cancel the upstream body when a chunk exceeds the maximum size', async () => {
261
+ const token = {
262
+ exportedSecret: new Uint8Array(32),
263
+ requestEnc: new Uint8Array(32),
264
+ };
265
+ let upstreamCancelled = false;
266
+ const upstream = new ReadableStream({
267
+ start(controller) {
268
+ // Oversized length prefix (~4 GiB); a real attacker keeps streaming.
269
+ controller.enqueue(new Uint8Array([0xff, 0xff, 0xff, 0xff, 0x00]));
270
+ },
271
+ cancel() {
272
+ upstreamCancelled = true;
273
+ },
274
+ });
275
+ const nonce = bytesToHex(new Uint8Array(RESPONSE_NONCE_LENGTH));
276
+ const response = new Response(upstream, {
277
+ status: 200,
278
+ headers: { [PROTOCOL.RESPONSE_NONCE_HEADER]: nonce },
279
+ });
280
+ const decrypted = await decryptResponseWithToken(response, token);
281
+ await assert.rejects(() => decrypted.text(), /maximum allowed size/);
282
+ assert.strictEqual(upstreamCancelled, true, 'upstream body should be cancelled on oversized chunk');
283
+ });
284
+ it('should fail decryption with a wrong token', async () => {
285
+ const { identity, privateKey } = await generateTestKeys();
286
+ const request = new Request('https://server.test/api', {
287
+ method: 'POST',
288
+ body: 'hello',
289
+ });
290
+ const { request: encryptedRequest, context } = await identity.encryptRequestWithContext(request);
291
+ assert(context);
292
+ const encryptedResponse = await buildEncryptedResponse(encryptedRequest, privateKey, 'secret');
293
+ // Forge a token with random bytes — decryption must fail
294
+ const badToken = {
295
+ exportedSecret: crypto.getRandomValues(new Uint8Array(32)),
296
+ requestEnc: crypto.getRandomValues(new Uint8Array(32)),
297
+ };
298
+ const decrypted = await decryptResponseWithToken(encryptedResponse, badToken);
299
+ // The stream-level decryption fails when you actually try to read
300
+ await assert.rejects(() => decrypted.text(), /Decryption failed/);
301
+ });
302
+ });
303
+ describe('decryptResponseWithContext delegates to token path', () => {
304
+ it('should produce identical plaintext via context path and token path', async () => {
305
+ const { identity, privateKey } = await generateTestKeys();
306
+ // We need two identical requests since Response bodies are consumed once.
307
+ // Instead, we build two responses from the same server-side state.
308
+ const request = new Request('https://server.test/api', {
309
+ method: 'POST',
310
+ body: 'payload',
311
+ });
312
+ const { request: encryptedRequest, context } = await identity.encryptRequestWithContext(request);
313
+ assert(context);
314
+ const token = await extractSessionRecoveryToken(context);
315
+ // Build one encrypted response for the token path
316
+ const responseForToken = await buildEncryptedResponse(encryptedRequest.clone(), privateKey, 'identical-response');
317
+ const decryptedViaToken = await decryptResponseWithToken(responseForToken, token);
318
+ const textViaToken = await decryptedViaToken.text();
319
+ assert.strictEqual(textViaToken, 'identical-response');
320
+ });
321
+ });
322
+ describe('token serialization round-trip (simulating localStorage)', () => {
323
+ it('should work after JSON serialization and deserialization', async () => {
324
+ const { identity, privateKey } = await generateTestKeys();
325
+ const request = new Request('https://server.test/api', {
326
+ method: 'POST',
327
+ body: 'test',
328
+ });
329
+ const { request: encryptedRequest, context } = await identity.encryptRequestWithContext(request);
330
+ assert(context);
331
+ const originalToken = await extractSessionRecoveryToken(context);
332
+ // Simulate localStorage: serialize to JSON and back using hex helpers
333
+ const serialized = serializeSessionRecoveryToken(originalToken);
334
+ // Verify the JSON contains hex strings
335
+ const raw = JSON.parse(serialized);
336
+ assert.strictEqual(raw.exportedSecret, bytesToHex(originalToken.exportedSecret));
337
+ assert.strictEqual(raw.requestEnc, bytesToHex(originalToken.requestEnc));
338
+ const restoredToken = deserializeSessionRecoveryToken(serialized);
339
+ // Decrypt with the deserialized token
340
+ const encryptedResponse = await buildEncryptedResponse(encryptedRequest, privateKey, 'recovered after tab close');
341
+ const decrypted = await decryptResponseWithToken(encryptedResponse, restoredToken);
342
+ const text = await decrypted.text();
343
+ assert.strictEqual(text, 'recovered after tab close');
344
+ });
345
+ });
346
+ describe('interoperability test vector', () => {
347
+ it('should deserialize the shared fixture and re-serialize to identical JSON', () => {
348
+ const thisDir = dirname(fileURLToPath(import.meta.url));
349
+ const vectorPath = resolve(thisDir, '../../../../test-vectors/session-recovery-token.json');
350
+ const vectorJSON = readFileSync(vectorPath, 'utf-8');
351
+ const token = deserializeSessionRecoveryToken(vectorJSON);
352
+ assert.strictEqual(token.exportedSecret.length, 32, 'exportedSecret must be 32 bytes');
353
+ assert.strictEqual(token.requestEnc.length, 32, 'requestEnc must be 32 bytes');
354
+ assert.strictEqual(bytesToHex(token.exportedSecret), 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2');
355
+ assert.strictEqual(bytesToHex(token.requestEnc), '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef');
356
+ // Re-serialize and verify identical JSON content
357
+ const reserialized = serializeSessionRecoveryToken(token);
358
+ assert.deepStrictEqual(JSON.parse(reserialized), JSON.parse(vectorJSON));
359
+ });
360
+ });
361
+ describe('response decryption interop vector', () => {
362
+ it('should decrypt the shared response-decryption fixture', async () => {
363
+ const thisDir = dirname(fileURLToPath(import.meta.url));
364
+ const vectorPath = resolve(thisDir, '../../../../test-vectors/response-decryption.json');
365
+ const vector = JSON.parse(readFileSync(vectorPath, 'utf-8'));
366
+ const token = {
367
+ exportedSecret: hexToBytes(vector.exportedSecret),
368
+ requestEnc: hexToBytes(vector.requestEnc),
369
+ };
370
+ const responseNonce = hexToBytes(vector.responseNonce);
371
+ const expectedPlaintext = hexToBytes(vector.plaintext);
372
+ const encryptedResponse = hexToBytes(vector.encryptedResponse);
373
+ const km = await deriveResponseKeys(token.exportedSecret, token.requestEnc, responseNonce);
374
+ // Parse chunked framing: LEN (4 bytes) || ciphertext
375
+ const chunkLen = (encryptedResponse[0] << 24) | (encryptedResponse[1] << 16) |
376
+ (encryptedResponse[2] << 8) | encryptedResponse[3];
377
+ const ciphertext = encryptedResponse.slice(4, 4 + chunkLen);
378
+ const decrypted = await decryptChunk(km, 0, ciphertext);
379
+ assert.deepStrictEqual(decrypted, expectedPlaintext);
380
+ });
381
+ });
382
+ describe('Transport.getSessionRecoveryToken', () => {
383
+ it('should throw before any request is made', async () => {
384
+ const { identity } = await generateTestKeys();
385
+ const { Transport } = await import('../client.js');
386
+ const transport = new Transport(identity, 'server.test');
387
+ assert.throws(() => transport.getSessionRecoveryToken(), /No session recovery token available/);
388
+ });
389
+ it('should return a working token after a request', async () => {
390
+ const { identity, privateKey } = await generateTestKeys();
391
+ const { Transport } = await import('../client.js');
392
+ const transport = new Transport(identity, 'server.test');
393
+ const originalFetch = globalThis.fetch;
394
+ globalThis.fetch = (async (input) => {
395
+ const request = input instanceof Request ? input : new Request(input);
396
+ return buildEncryptedResponse(request, privateKey, 'via-transport');
397
+ });
398
+ try {
399
+ const response = await transport.post('https://server.test/api', 'body');
400
+ const responseText = await response.text();
401
+ assert.strictEqual(responseText, 'via-transport');
402
+ // The token should now be available
403
+ const token = transport.getSessionRecoveryToken();
404
+ assert.strictEqual(token.exportedSecret.length, 32);
405
+ assert.strictEqual(token.requestEnc.length, 32);
406
+ }
407
+ finally {
408
+ globalThis.fetch = originalFetch;
409
+ }
410
+ });
411
+ it('should update the token on each new request', async () => {
412
+ const { identity, privateKey } = await generateTestKeys();
413
+ const { Transport } = await import('../client.js');
414
+ const transport = new Transport(identity, 'server.test');
415
+ const originalFetch = globalThis.fetch;
416
+ globalThis.fetch = (async (input) => {
417
+ const request = input instanceof Request ? input : new Request(input);
418
+ return buildEncryptedResponse(request, privateKey, 'ok');
419
+ });
420
+ try {
421
+ await transport.post('https://server.test/api', 'request-1');
422
+ const token1 = transport.getSessionRecoveryToken();
423
+ await transport.post('https://server.test/api', 'request-2');
424
+ const token2 = transport.getSessionRecoveryToken();
425
+ // Each request creates a fresh HPKE context
426
+ assert.notDeepStrictEqual(token1.exportedSecret, token2.exportedSecret, 'Tokens from different requests must have different exported secrets');
427
+ }
428
+ finally {
429
+ globalThis.fetch = originalFetch;
430
+ }
431
+ });
432
+ it('should clear the token for bodyless requests', async () => {
433
+ const { identity, privateKey } = await generateTestKeys();
434
+ const { Transport } = await import('../client.js');
435
+ const transport = new Transport(identity, 'server.test');
436
+ const originalFetch = globalThis.fetch;
437
+ globalThis.fetch = (async (input) => {
438
+ const request = input instanceof Request ? input : new Request(input);
439
+ const hasEncKey = request.headers.has(PROTOCOL.ENCAPSULATED_KEY_HEADER);
440
+ if (hasEncKey) {
441
+ return buildEncryptedResponse(request, privateKey, 'encrypted');
442
+ }
443
+ return new Response('plaintext');
444
+ });
445
+ try {
446
+ // POST with body — token should be set
447
+ await transport.post('https://server.test/api', 'body');
448
+ const tokenAfterPost = transport.getSessionRecoveryToken();
449
+ assert(tokenAfterPost, 'Token should exist after POST with body');
450
+ // GET without body — token should be cleared
451
+ await transport.get('https://server.test/api');
452
+ assert.throws(() => transport.getSessionRecoveryToken(), /No session recovery token available/, 'Token should be cleared after bodyless request');
453
+ }
454
+ finally {
455
+ globalThis.fetch = originalFetch;
456
+ }
457
+ });
458
+ });
459
+ });
460
+ //# sourceMappingURL=session-recovery.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-recovery.test.js","sourceRoot":"","sources":["../../../src/test/session-recovery.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ehbp",
3
- "version": "0.1.7",
3
+ "version": "0.2.1",
4
4
  "description": "JavaScript client for Encrypted HTTP Body Protocol (EHBP)",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",