@storacha/encrypt-upload-client 1.1.64 → 1.1.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/test/crypto-streaming.spec.js.map +1 -0
  2. package/dist/test/encrypted-metadata.spec.js.map +1 -0
  3. package/dist/test/factories.spec.js.map +1 -0
  4. package/dist/test/file-metadata.spec.js.map +1 -0
  5. package/package.json +2 -2
  6. package/dist/examples/decrypt-test.d.ts +0 -2
  7. package/dist/examples/decrypt-test.d.ts.map +0 -1
  8. package/dist/examples/decrypt-test.js +0 -73
  9. package/dist/examples/encrypt-test.d.ts +0 -4
  10. package/dist/examples/encrypt-test.d.ts.map +0 -1
  11. package/dist/examples/encrypt-test.js +0 -61
  12. package/dist/test/fixtures/test-fixtures.d.ts +0 -28
  13. package/dist/test/fixtures/test-fixtures.d.ts.map +0 -1
  14. package/dist/test/fixtures/test-fixtures.js +0 -63
  15. package/dist/test/https-enforcement.spec.d.ts +0 -2
  16. package/dist/test/https-enforcement.spec.d.ts.map +0 -1
  17. package/dist/test/https-enforcement.spec.js +0 -125
  18. package/dist/test/kms-crypto-adapter.spec.d.ts +0 -2
  19. package/dist/test/kms-crypto-adapter.spec.d.ts.map +0 -1
  20. package/dist/test/kms-crypto-adapter.spec.js +0 -305
  21. package/dist/test/lit-crypto-adapter.spec.d.ts +0 -2
  22. package/dist/test/lit-crypto-adapter.spec.d.ts.map +0 -1
  23. package/dist/test/lit-crypto-adapter.spec.js +0 -120
  24. package/dist/test/memory-efficiency.spec.d.ts +0 -2
  25. package/dist/test/memory-efficiency.spec.d.ts.map +0 -1
  26. package/dist/test/memory-efficiency.spec.js +0 -93
  27. package/dist/test/mocks/key-manager.d.ts +0 -58
  28. package/dist/test/mocks/key-manager.d.ts.map +0 -1
  29. package/dist/test/mocks/key-manager.js +0 -137
  30. package/dist/test/node-crypto-adapter.spec.d.ts +0 -2
  31. package/dist/test/node-crypto-adapter.spec.d.ts.map +0 -1
  32. package/dist/test/node-crypto-adapter.spec.js +0 -103
  33. package/dist/test/node-generic-crypto-adapter.spec.d.ts +0 -2
  34. package/dist/test/node-generic-crypto-adapter.spec.d.ts.map +0 -1
  35. package/dist/test/node-generic-crypto-adapter.spec.js +0 -95
  36. package/dist/tsconfig.spec.tsbuildinfo +0 -1
@@ -1,137 +0,0 @@
1
- import { createServer } from 'node:http';
2
- import * as Server from '@ucanto/server';
3
- import { CAR } from '@ucanto/transport';
4
- import * as Space from '@storacha/capabilities/space';
5
- import { base64 } from 'multiformats/bases/base64';
6
- /**
7
- * Create mock KMS service with proper capability handlers
8
- *
9
- * @param {object} options
10
- * @param {string} options.mockPublicKey - Mock RSA public key in PEM format
11
- * @param {string} [options.mockProvider] - Mock KMS provider
12
- * @param {string} [options.mockAlgorithm] - Mock algorithm
13
- * @param {Function} [options.onEncryptionSetup] - Optional callback for setup calls
14
- * @param {Function} [options.onKeyDecrypt] - Optional callback for decrypt calls
15
- */
16
- export function createMockKeyManagerService(options) {
17
- const { mockPublicKey, mockProvider = 'google-kms', mockAlgorithm = 'RSA-OAEP-2048-SHA256', onEncryptionSetup, onKeyDecrypt, } = options;
18
- return {
19
- space: {
20
- encryption: {
21
- setup: Server.provide(Space.EncryptionSetup, async (input) => {
22
- // Call optional callback for testing
23
- if (onEncryptionSetup) {
24
- onEncryptionSetup(input);
25
- }
26
- // Validate the space DID format
27
- if (!input.capability.with.startsWith('did:key:')) {
28
- return Server.error({
29
- name: 'InvalidSpace',
30
- message: 'Space DID must be a did:key',
31
- });
32
- }
33
- // Return mock RSA public key and metadata
34
- return Server.ok({
35
- publicKey: mockPublicKey,
36
- provider: mockProvider,
37
- algorithm: mockAlgorithm,
38
- });
39
- }),
40
- key: {
41
- decrypt: Server.provide(Space.EncryptionKeyDecrypt, async (input) => {
42
- // Call optional callback for testing
43
- if (onKeyDecrypt) {
44
- onKeyDecrypt(input);
45
- }
46
- // Validate the space DID
47
- if (!input.capability.with.startsWith('did:key:')) {
48
- return Server.error({
49
- name: 'InvalidSpace',
50
- message: 'Space DID must be a did:key',
51
- });
52
- }
53
- // Validate encrypted key is provided
54
- if (!input.capability.nb.key) {
55
- return Server.error({
56
- name: 'KeyNotFound',
57
- message: 'key is required',
58
- });
59
- }
60
- // For testing purposes, "decrypt" by converting bytes back to base64 string
61
- // In real implementation, this would call Google KMS
62
- const keyBytes = input.capability.nb.key;
63
- // No base64 decode here, just return the bytes as base64 string for mock
64
- const mockDecryptedKey = base64.encode(keyBytes);
65
- return Server.ok({
66
- decryptedSymmetricKey: mockDecryptedKey,
67
- });
68
- }),
69
- },
70
- },
71
- },
72
- };
73
- }
74
- /**
75
- * Create a mock key manager service server
76
- *
77
- * @param {object} service - The service object with capability handlers
78
- * @param {*} keyManagerServiceDID - The key manager service DID keypair
79
- * @param {number} port - The port to listen on
80
- * @param {boolean} [useHttps] - Whether to use HTTPS URLs (testing HTTPS scenarios)
81
- */
82
- export function createMockKeyManagerServer(service, keyManagerServiceDID, port, useHttps = false) {
83
- const ucantoServer = Server.create({
84
- id: keyManagerServiceDID,
85
- service,
86
- codec: CAR.inbound,
87
- validateAuthorization: () => ({ ok: {} }), // Skip auth validation for tests
88
- });
89
- const httpServer = createServer(async (req, res) => {
90
- res.setHeader('Access-Control-Allow-Origin', '*');
91
- res.setHeader('Access-Control-Allow-Methods', '*');
92
- res.setHeader('Access-Control-Allow-Headers', '*');
93
- if (req.method === 'OPTIONS')
94
- return res.end();
95
- if (req.method === 'POST') {
96
- const bodyBuffer = Buffer.concat(await collect(req));
97
- const reqHeaders = /** @type {Record<string, string>} */ (Object.fromEntries(Object.entries(req.headers)));
98
- const { headers, body, status } = await ucantoServer.request({
99
- body: new Uint8Array(bodyBuffer.buffer, bodyBuffer.byteOffset, bodyBuffer.byteLength),
100
- headers: reqHeaders,
101
- });
102
- for (const [key, value] of Object.entries(headers)) {
103
- res.setHeader(key, value);
104
- }
105
- res.writeHead(status ?? 200);
106
- res.end(body);
107
- }
108
- else {
109
- res.end();
110
- }
111
- });
112
- return new Promise((resolve, reject) => {
113
- httpServer.listen(port, (/** @type {Error | undefined} */ err) => {
114
- if (err) {
115
- reject(err);
116
- }
117
- else {
118
- const protocol = useHttps ? 'https' : 'http';
119
- resolve({
120
- server: httpServer,
121
- url: `${protocol}://localhost:${port}`,
122
- close: () => new Promise((resolve) => httpServer.close(resolve)),
123
- });
124
- }
125
- });
126
- });
127
- }
128
- /** @param {import('node:stream').Readable} stream */
129
- const collect = (stream) => {
130
- return /** @type {Promise<Buffer[]>} */ (new Promise((resolve, reject) => {
131
- const chunks = /** @type {Buffer[]} */ ([]);
132
- stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
133
- stream.on('error', (err) => reject(err));
134
- stream.on('end', () => resolve(chunks));
135
- }));
136
- };
137
- //# sourceMappingURL=key-manager.js.map
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=node-crypto-adapter.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"node-crypto-adapter.spec.d.ts","sourceRoot":"","sources":["../../test/node-crypto-adapter.spec.js"],"names":[],"mappings":""}
@@ -1,103 +0,0 @@
1
- import { test, describe } from 'node:test';
2
- import assert from 'node:assert';
3
- import { NodeAesCbcCrypto } from '../src/crypto/symmetric/node-aes-cbc-crypto.js';
4
- import { stringToUint8Array, uint8ArrayToString, streamToUint8Array, createMockBlob, } from './helpers/test-file-utils.js';
5
- await describe('NodeAesCbcCrypto', async () => {
6
- await test('should encrypt and decrypt data and return the original data', async () => {
7
- const adapter = new NodeAesCbcCrypto();
8
- const originalText = 'Hello, this is a test for Node.js AES-CBC encryption!';
9
- const mockBlob = createMockBlob(stringToUint8Array(originalText));
10
- // Encrypt
11
- const { key, iv, encryptedStream } = await adapter.encryptStream(mockBlob);
12
- // Decrypt
13
- const decryptedStream = await adapter.decryptStream(encryptedStream, key, iv);
14
- const decryptedBytes = await streamToUint8Array(decryptedStream);
15
- const decryptedText = uint8ArrayToString(decryptedBytes);
16
- assert.strictEqual(decryptedText, originalText);
17
- });
18
- await test('should handle empty data', async () => {
19
- const adapter = new NodeAesCbcCrypto();
20
- const mockBlob = createMockBlob(new Uint8Array(0));
21
- const { key, iv, encryptedStream } = await adapter.encryptStream(mockBlob);
22
- const decryptedStream = await adapter.decryptStream(encryptedStream, key, iv);
23
- const decryptedBytes = await streamToUint8Array(decryptedStream);
24
- assert.strictEqual(decryptedBytes.length, 0);
25
- });
26
- await test('should combine key and IV correctly', async () => {
27
- const adapter = new NodeAesCbcCrypto();
28
- const key = new Uint8Array(32).fill(3); // 32-byte AES-256 key
29
- const iv = new Uint8Array(16).fill(6); // 16-byte AES-CBC IV
30
- const combined = adapter.combineKeyAndIV(key, iv);
31
- assert.strictEqual(combined.length, 48, 'Combined length should be 48 bytes (32 + 16)');
32
- // Verify first 32 bytes are the key
33
- for (let i = 0; i < 32; i++) {
34
- assert.strictEqual(combined[i], 3, `Key byte ${i} should match`);
35
- }
36
- // Verify last 16 bytes are the IV
37
- for (let i = 32; i < 48; i++) {
38
- assert.strictEqual(combined[i], 6, `IV byte ${i - 32} should match`);
39
- }
40
- });
41
- await test('should split combined key and IV correctly', async () => {
42
- const adapter = new NodeAesCbcCrypto();
43
- const originalKey = new Uint8Array(32).fill(123);
44
- const originalIV = new Uint8Array(16).fill(234);
45
- const combined = adapter.combineKeyAndIV(originalKey, originalIV);
46
- const { key, iv } = adapter.splitKeyAndIV(combined);
47
- assert.strictEqual(key.length, 32, 'Split key should be 32 bytes');
48
- assert.strictEqual(iv.length, 16, 'Split IV should be 16 bytes');
49
- // Verify key matches
50
- for (let i = 0; i < 32; i++) {
51
- assert.strictEqual(key[i], originalKey[i], `Key byte ${i} should match original`);
52
- }
53
- // Verify IV matches
54
- for (let i = 0; i < 16; i++) {
55
- assert.strictEqual(iv[i], originalIV[i], `IV byte ${i} should match original`);
56
- }
57
- });
58
- await test('should roundtrip combine/split correctly', async () => {
59
- const adapter = new NodeAesCbcCrypto();
60
- const { randomBytes } = await import('crypto');
61
- // Convert Buffer to Uint8Array to match the expected types
62
- const originalKey = new Uint8Array(randomBytes(32));
63
- const originalIV = new Uint8Array(randomBytes(16));
64
- const combined = adapter.combineKeyAndIV(originalKey, originalIV);
65
- const { key, iv } = adapter.splitKeyAndIV(combined);
66
- assert.deepStrictEqual(key, originalKey, 'Roundtrip key should match original');
67
- assert.deepStrictEqual(iv, originalIV, 'Roundtrip IV should match original');
68
- });
69
- await test('should validate key length in combineKeyAndIV', async () => {
70
- const adapter = new NodeAesCbcCrypto();
71
- const wrongKey = new Uint8Array(31); // Wrong size
72
- const correctIV = new Uint8Array(16);
73
- assert.throws(() => adapter.combineKeyAndIV(wrongKey, correctIV), {
74
- name: 'Error',
75
- message: 'AES-256 key must be 32 bytes, got 31',
76
- }, 'Should throw error for wrong key size');
77
- });
78
- await test('should validate IV length in combineKeyAndIV', async () => {
79
- const adapter = new NodeAesCbcCrypto();
80
- const correctKey = new Uint8Array(32);
81
- const wrongIV = new Uint8Array(15); // Wrong size
82
- assert.throws(() => adapter.combineKeyAndIV(correctKey, wrongIV), {
83
- name: 'Error',
84
- message: 'AES-CBC IV must be 16 bytes, got 15',
85
- }, 'Should throw error for wrong IV size');
86
- });
87
- await test('should validate combined length in splitKeyAndIV', async () => {
88
- const adapter = new NodeAesCbcCrypto();
89
- const wrongCombined = new Uint8Array(47); // Wrong size
90
- assert.throws(() => adapter.splitKeyAndIV(wrongCombined), {
91
- name: 'Error',
92
- message: 'AES-256-CBC combined key+IV must be 48 bytes, got 47',
93
- }, 'Should throw error for wrong combined size');
94
- });
95
- await test('should use constants for validation', async () => {
96
- const adapter = new NodeAesCbcCrypto();
97
- // Test with different wrong sizes to ensure constants are used
98
- assert.throws(() => adapter.combineKeyAndIV(new Uint8Array(16), new Uint8Array(16)), /AES-256 key must be 32 bytes, got 16/, 'Should use KEY_LENGTH constant in error message');
99
- assert.throws(() => adapter.combineKeyAndIV(new Uint8Array(32), new Uint8Array(8)), /AES-CBC IV must be 16 bytes, got 8/, 'Should use IV_LENGTH constant in error message');
100
- assert.throws(() => adapter.splitKeyAndIV(new Uint8Array(32)), /AES-256-CBC combined key\+IV must be 48 bytes, got 32/, 'Should use calculated expected length in error message');
101
- });
102
- });
103
- //# sourceMappingURL=node-crypto-adapter.spec.js.map
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=node-generic-crypto-adapter.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"node-generic-crypto-adapter.spec.d.ts","sourceRoot":"","sources":["../../test/node-generic-crypto-adapter.spec.js"],"names":[],"mappings":""}
@@ -1,95 +0,0 @@
1
- import './setup.js';
2
- import { test, describe } from 'node:test';
3
- import assert from 'node:assert';
4
- import { GenericAesCtrStreamingCrypto } from '../src/crypto/symmetric/generic-aes-ctr-streaming-crypto.js';
5
- import { stringToUint8Array, streamToUint8Array, uint8ArrayToString, } from './helpers/test-file-utils.js';
6
- await describe('GenericAesCtrStreamingCrypto (Node Environment)', async () => {
7
- await test('should encrypt and decrypt a Blob and return the original data', async () => {
8
- const adapter = new GenericAesCtrStreamingCrypto();
9
- const originalText = 'Op, this is a test for streaming encryption!';
10
- const blob = new Blob([stringToUint8Array(originalText)]);
11
- // Encrypt
12
- const { key, iv, encryptedStream } = await adapter.encryptStream(blob);
13
- // Decrypt
14
- const decryptedStream = await adapter.decryptStream(encryptedStream, key, iv);
15
- const decryptedBytes = await streamToUint8Array(decryptedStream);
16
- const decryptedText = uint8ArrayToString(decryptedBytes);
17
- assert.strictEqual(decryptedText, originalText);
18
- });
19
- await test('should handle empty data', async () => {
20
- const adapter = new GenericAesCtrStreamingCrypto();
21
- const blob = new Blob([]);
22
- const { key, iv, encryptedStream } = await adapter.encryptStream(blob);
23
- const decryptedStream = await adapter.decryptStream(encryptedStream, key, iv);
24
- const decryptedBytes = await streamToUint8Array(decryptedStream);
25
- assert.strictEqual(decryptedBytes.length, 0);
26
- });
27
- await test('should combine key and IV correctly', async () => {
28
- const adapter = new GenericAesCtrStreamingCrypto();
29
- const key = new Uint8Array(32).fill(1); // 32-byte AES-256 key
30
- const iv = new Uint8Array(16).fill(2); // 16-byte AES-CTR IV
31
- const combined = adapter.combineKeyAndIV(key, iv);
32
- assert.strictEqual(combined.length, 48, 'Combined length should be 48 bytes (32 + 16)');
33
- // Verify first 32 bytes are the key
34
- for (let i = 0; i < 32; i++) {
35
- assert.strictEqual(combined[i], 1, `Key byte ${i} should match`);
36
- }
37
- // Verify last 16 bytes are the IV
38
- for (let i = 32; i < 48; i++) {
39
- assert.strictEqual(combined[i], 2, `IV byte ${i - 32} should match`);
40
- }
41
- });
42
- await test('should split combined key and IV correctly', async () => {
43
- const adapter = new GenericAesCtrStreamingCrypto();
44
- const originalKey = new Uint8Array(32).fill(42);
45
- const originalIV = new Uint8Array(16).fill(84);
46
- const combined = adapter.combineKeyAndIV(originalKey, originalIV);
47
- const { key, iv } = adapter.splitKeyAndIV(combined);
48
- assert.strictEqual(key.length, 32, 'Split key should be 32 bytes');
49
- assert.strictEqual(iv.length, 16, 'Split IV should be 16 bytes');
50
- // Verify key matches
51
- for (let i = 0; i < 32; i++) {
52
- assert.strictEqual(key[i], originalKey[i], `Key byte ${i} should match original`);
53
- }
54
- // Verify IV matches
55
- for (let i = 0; i < 16; i++) {
56
- assert.strictEqual(iv[i], originalIV[i], `IV byte ${i} should match original`);
57
- }
58
- });
59
- await test('should roundtrip combine/split correctly', async () => {
60
- const adapter = new GenericAesCtrStreamingCrypto();
61
- const originalKey = globalThis.crypto.getRandomValues(new Uint8Array(32));
62
- const originalIV = globalThis.crypto.getRandomValues(new Uint8Array(16));
63
- const combined = adapter.combineKeyAndIV(originalKey, originalIV);
64
- const { key, iv } = adapter.splitKeyAndIV(combined);
65
- assert.deepStrictEqual(key, originalKey, 'Roundtrip key should match original');
66
- assert.deepStrictEqual(iv, originalIV, 'Roundtrip IV should match original');
67
- });
68
- await test('should validate key length in combineKeyAndIV', async () => {
69
- const adapter = new GenericAesCtrStreamingCrypto();
70
- const wrongKey = new Uint8Array(31); // Wrong size
71
- const correctIV = new Uint8Array(16);
72
- assert.throws(() => adapter.combineKeyAndIV(wrongKey, correctIV), {
73
- name: 'Error',
74
- message: 'AES-256 key must be 32 bytes, got 31',
75
- }, 'Should throw error for wrong key size');
76
- });
77
- await test('should validate IV length in combineKeyAndIV', async () => {
78
- const adapter = new GenericAesCtrStreamingCrypto();
79
- const correctKey = new Uint8Array(32);
80
- const wrongIV = new Uint8Array(15); // Wrong size
81
- assert.throws(() => adapter.combineKeyAndIV(correctKey, wrongIV), {
82
- name: 'Error',
83
- message: 'AES-CTR IV must be 16 bytes, got 15',
84
- }, 'Should throw error for wrong IV size');
85
- });
86
- await test('should validate combined length in splitKeyAndIV', async () => {
87
- const adapter = new GenericAesCtrStreamingCrypto();
88
- const wrongCombined = new Uint8Array(47); // Wrong size
89
- assert.throws(() => adapter.splitKeyAndIV(wrongCombined), {
90
- name: 'Error',
91
- message: 'AES-256-CTR combined key+IV must be 48 bytes, got 47',
92
- }, 'Should throw error for wrong combined size');
93
- });
94
- });
95
- //# sourceMappingURL=node-generic-crypto-adapter.spec.js.map