wolfronix-sdk 1.1.0 → 1.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/README.md CHANGED
@@ -16,6 +16,17 @@ Official JavaScript/TypeScript SDK for Wolfronix - Zero-knowledge encryption mad
16
16
  - ⚡ **Streaming** - Handle large files with progress tracking
17
17
  - 🔄 **Auto Retry** - Built-in retry logic with exponential backoff
18
18
 
19
+ ## Backend Integration (Enterprise Mode)
20
+
21
+ To use this SDK, your backend API must implement 3 storage endpoints that Wolfronix will call:
22
+
23
+ 1. **POST** `/wolfronix/files/upload` - Store encrypted file + metadata
24
+ 2. **GET** `/wolfronix/files/{id}` - Retrieve metadata
25
+ 3. **GET** `/wolfronix/files/{id}/data` - Retrieve encrypted file blob
26
+
27
+ Wolfronix handles all encryption/decryption keys and logic; you only handle the encrypted blobs.
28
+
29
+
19
30
  ## Installation
20
31
 
21
32
  ```bash
@@ -37,7 +48,10 @@ const wfx = new Wolfronix({
37
48
  clientId: 'your-enterprise-client-id'
38
49
  });
39
50
 
40
- // Login
51
+ // Register (First time only) - Generates keys client-side
52
+ await wfx.register('user@example.com', 'password123');
53
+
54
+ // Login (Subsequent visits)
41
55
  await wfx.login('user@example.com', 'password123');
42
56
 
43
57
  // Encrypt a file
package/dist/index.d.mts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Zero-knowledge encryption made simple
4
4
  *
5
5
  * @package @wolfronix/sdk
6
- * @version 1.1.0
6
+ * @version 1.2.0
7
7
  */
8
8
  interface WolfronixConfig {
9
9
  /** Wolfronix server base URL */
@@ -24,11 +24,10 @@ interface AuthResponse {
24
24
  message: string;
25
25
  }
26
26
  interface EncryptResponse {
27
- success: boolean;
28
- file_id: string;
29
- original_name: string;
30
- encrypted_size: number;
31
- message: string;
27
+ status: string;
28
+ file_id: number;
29
+ file_size: number;
30
+ enc_time_ms: number;
32
31
  }
33
32
  interface FileInfo {
34
33
  file_id: string;
@@ -52,10 +51,6 @@ interface MetricsResponse {
52
51
  total_bytes_encrypted: number;
53
52
  total_bytes_decrypted: number;
54
53
  }
55
- interface StreamToken {
56
- token: string;
57
- expires_at: string;
58
- }
59
54
  declare class WolfronixError extends Error {
60
55
  readonly code: string;
61
56
  readonly statusCode?: number;
@@ -155,17 +150,6 @@ declare class Wolfronix {
155
150
  * ```
156
151
  */
157
152
  encrypt(file: File | Blob | ArrayBuffer | Uint8Array, filename?: string): Promise<EncryptResponse>;
158
- /**
159
- * Encrypt a file using streaming (for large files)
160
- *
161
- * @example
162
- * ```typescript
163
- * const result = await wfx.encryptStream(largeFile, (progress) => {
164
- * console.log(`Progress: ${progress}%`);
165
- * });
166
- * ```
167
- */
168
- encryptStream(file: File | Blob, onProgress?: (percent: number) => void): Promise<EncryptResponse>;
169
153
  /**
170
154
  * Decrypt and retrieve a file
171
155
  *
@@ -185,10 +169,6 @@ declare class Wolfronix {
185
169
  * Decrypt and return as ArrayBuffer
186
170
  */
187
171
  decryptToBuffer(fileId: string): Promise<ArrayBuffer>;
188
- /**
189
- * Decrypt using streaming (for large files)
190
- */
191
- decryptStream(fileId: string, onProgress?: (percent: number) => void): Promise<Blob>;
192
172
  /**
193
173
  * List all encrypted files for current user
194
174
  *
@@ -238,4 +218,4 @@ declare class Wolfronix {
238
218
  */
239
219
  declare function createClient(config: WolfronixConfig | string): Wolfronix;
240
220
 
241
- export { type AuthResponse, AuthenticationError, type DeleteResponse, type EncryptResponse, type FileInfo, FileNotFoundError, type ListFilesResponse, type MetricsResponse, NetworkError, PermissionDeniedError, type StreamToken, ValidationError, Wolfronix, type WolfronixConfig, WolfronixError, createClient, Wolfronix as default };
221
+ export { type AuthResponse, AuthenticationError, type DeleteResponse, type EncryptResponse, type FileInfo, FileNotFoundError, type ListFilesResponse, type MetricsResponse, NetworkError, PermissionDeniedError, ValidationError, Wolfronix, type WolfronixConfig, WolfronixError, createClient, Wolfronix as default };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Zero-knowledge encryption made simple
4
4
  *
5
5
  * @package @wolfronix/sdk
6
- * @version 1.1.0
6
+ * @version 1.2.0
7
7
  */
8
8
  interface WolfronixConfig {
9
9
  /** Wolfronix server base URL */
@@ -24,11 +24,10 @@ interface AuthResponse {
24
24
  message: string;
25
25
  }
26
26
  interface EncryptResponse {
27
- success: boolean;
28
- file_id: string;
29
- original_name: string;
30
- encrypted_size: number;
31
- message: string;
27
+ status: string;
28
+ file_id: number;
29
+ file_size: number;
30
+ enc_time_ms: number;
32
31
  }
33
32
  interface FileInfo {
34
33
  file_id: string;
@@ -52,10 +51,6 @@ interface MetricsResponse {
52
51
  total_bytes_encrypted: number;
53
52
  total_bytes_decrypted: number;
54
53
  }
55
- interface StreamToken {
56
- token: string;
57
- expires_at: string;
58
- }
59
54
  declare class WolfronixError extends Error {
60
55
  readonly code: string;
61
56
  readonly statusCode?: number;
@@ -155,17 +150,6 @@ declare class Wolfronix {
155
150
  * ```
156
151
  */
157
152
  encrypt(file: File | Blob | ArrayBuffer | Uint8Array, filename?: string): Promise<EncryptResponse>;
158
- /**
159
- * Encrypt a file using streaming (for large files)
160
- *
161
- * @example
162
- * ```typescript
163
- * const result = await wfx.encryptStream(largeFile, (progress) => {
164
- * console.log(`Progress: ${progress}%`);
165
- * });
166
- * ```
167
- */
168
- encryptStream(file: File | Blob, onProgress?: (percent: number) => void): Promise<EncryptResponse>;
169
153
  /**
170
154
  * Decrypt and retrieve a file
171
155
  *
@@ -185,10 +169,6 @@ declare class Wolfronix {
185
169
  * Decrypt and return as ArrayBuffer
186
170
  */
187
171
  decryptToBuffer(fileId: string): Promise<ArrayBuffer>;
188
- /**
189
- * Decrypt using streaming (for large files)
190
- */
191
- decryptStream(fileId: string, onProgress?: (percent: number) => void): Promise<Blob>;
192
172
  /**
193
173
  * List all encrypted files for current user
194
174
  *
@@ -238,4 +218,4 @@ declare class Wolfronix {
238
218
  */
239
219
  declare function createClient(config: WolfronixConfig | string): Wolfronix;
240
220
 
241
- export { type AuthResponse, AuthenticationError, type DeleteResponse, type EncryptResponse, type FileInfo, FileNotFoundError, type ListFilesResponse, type MetricsResponse, NetworkError, PermissionDeniedError, type StreamToken, ValidationError, Wolfronix, type WolfronixConfig, WolfronixError, createClient, Wolfronix as default };
221
+ export { type AuthResponse, AuthenticationError, type DeleteResponse, type EncryptResponse, type FileInfo, FileNotFoundError, type ListFilesResponse, type MetricsResponse, NetworkError, PermissionDeniedError, ValidationError, Wolfronix, type WolfronixConfig, WolfronixError, createClient, Wolfronix as default };
package/dist/index.js CHANGED
@@ -261,6 +261,9 @@ var Wolfronix = class {
261
261
  }
262
262
  if (includeAuth && this.token) {
263
263
  headers["Authorization"] = `Bearer ${this.token}`;
264
+ if (this.userId) {
265
+ headers["X-User-ID"] = this.userId;
266
+ }
264
267
  }
265
268
  return headers;
266
269
  }
@@ -493,57 +496,6 @@ var Wolfronix = class {
493
496
  formData
494
497
  });
495
498
  }
496
- /**
497
- * Encrypt a file using streaming (for large files)
498
- *
499
- * @example
500
- * ```typescript
501
- * const result = await wfx.encryptStream(largeFile, (progress) => {
502
- * console.log(`Progress: ${progress}%`);
503
- * });
504
- * ```
505
- */
506
- async encryptStream(file, onProgress) {
507
- this.ensureAuthenticated();
508
- const tokenResponse = await this.request("POST", "/api/v1/stream/token", {
509
- body: {
510
- user_id: this.userId,
511
- client_id: this.config.clientId
512
- }
513
- });
514
- const formData = new FormData();
515
- formData.append("file", file);
516
- formData.append("user_id", this.userId || "");
517
- formData.append("stream_token", tokenResponse.token);
518
- if (onProgress && typeof XMLHttpRequest !== "undefined") {
519
- return new Promise((resolve, reject) => {
520
- const xhr = new XMLHttpRequest();
521
- xhr.upload.onprogress = (event) => {
522
- if (event.lengthComputable) {
523
- onProgress(Math.round(event.loaded / event.total * 100));
524
- }
525
- };
526
- xhr.onload = () => {
527
- if (xhr.status >= 200 && xhr.status < 300) {
528
- resolve(JSON.parse(xhr.responseText));
529
- } else {
530
- reject(new WolfronixError("Upload failed", "UPLOAD_ERROR", xhr.status));
531
- }
532
- };
533
- xhr.onerror = () => reject(new NetworkError("Upload failed"));
534
- xhr.open("POST", `${this.config.baseUrl}/api/v1/stream/encrypt`);
535
- const headers = this.getHeaders();
536
- Object.entries(headers).forEach(([key, value]) => {
537
- xhr.setRequestHeader(key, value);
538
- });
539
- xhr.send(formData);
540
- });
541
- }
542
- return this.request("POST", "/api/v1/stream/encrypt", {
543
- formData
544
- // Stream endpoint might need update to accept public key too if re-implemented
545
- });
546
- }
547
499
  /**
548
500
  * Decrypt and retrieve a file
549
501
  *
@@ -567,9 +519,6 @@ var Wolfronix = class {
567
519
  throw new Error("Private key not available. Is user logged in?");
568
520
  }
569
521
  const privateKeyPEM = await exportKeyToPEM(this.privateKey, "private");
570
- const headers = this.getHeaders();
571
- headers["X-Private-Key"] = privateKeyPEM;
572
- headers["X-User-Role"] = "owner";
573
522
  return this.request("POST", `/api/v1/files/${fileId}/decrypt`, {
574
523
  responseType: "blob",
575
524
  headers: {
@@ -598,51 +547,6 @@ var Wolfronix = class {
598
547
  }
599
548
  });
600
549
  }
601
- /**
602
- * Decrypt using streaming (for large files)
603
- */
604
- async decryptStream(fileId, onProgress) {
605
- this.ensureAuthenticated();
606
- if (!fileId) {
607
- throw new ValidationError("File ID is required");
608
- }
609
- if (!this.privateKey) {
610
- throw new Error("Private key not available. Is user logged in?");
611
- }
612
- const privateKeyPEM = await exportKeyToPEM(this.privateKey, "private");
613
- if (onProgress && typeof XMLHttpRequest !== "undefined") {
614
- return new Promise((resolve, reject) => {
615
- const xhr = new XMLHttpRequest();
616
- xhr.responseType = "blob";
617
- xhr.onprogress = (event) => {
618
- if (event.lengthComputable) {
619
- onProgress(Math.round(event.loaded / event.total * 100));
620
- }
621
- };
622
- xhr.onload = () => {
623
- if (xhr.status >= 200 && xhr.status < 300) {
624
- resolve(xhr.response);
625
- } else {
626
- reject(new WolfronixError("Download failed", "DOWNLOAD_ERROR", xhr.status));
627
- }
628
- };
629
- xhr.onerror = () => reject(new NetworkError("Download failed"));
630
- xhr.open("POST", `${this.config.baseUrl}/api/v1/files/${fileId}/decrypt`);
631
- const headers = { ...this.getHeaders(), "X-Private-Key": privateKeyPEM, "X-User-Role": "owner" };
632
- Object.entries(headers).forEach(([key, value]) => {
633
- xhr.setRequestHeader(key, value);
634
- });
635
- xhr.send();
636
- });
637
- }
638
- return this.request("POST", `/api/v1/files/${fileId}/decrypt`, {
639
- responseType: "blob",
640
- headers: {
641
- "X-Private-Key": privateKeyPEM,
642
- "X-User-Role": "owner"
643
- }
644
- });
645
- }
646
550
  /**
647
551
  * List all encrypted files for current user
648
552
  *
@@ -654,7 +558,17 @@ var Wolfronix = class {
654
558
  */
655
559
  async listFiles() {
656
560
  this.ensureAuthenticated();
657
- return this.request("GET", "/api/v1/files");
561
+ const files = await this.request("GET", "/api/v1/files");
562
+ return {
563
+ success: true,
564
+ files: (files || []).map((f) => ({
565
+ file_id: f.id,
566
+ original_name: f.name,
567
+ encrypted_size: f.size_bytes,
568
+ created_at: f.date
569
+ })),
570
+ total: (files || []).length
571
+ };
658
572
  }
659
573
  /**
660
574
  * Delete an encrypted file
@@ -685,7 +599,7 @@ var Wolfronix = class {
685
599
  */
686
600
  async getMetrics() {
687
601
  this.ensureAuthenticated();
688
- return this.request("GET", "/api/v1/metrics");
602
+ return this.request("GET", "/api/v1/metrics/summary");
689
603
  }
690
604
  /**
691
605
  * Check if server is healthy
package/dist/index.mjs CHANGED
@@ -227,6 +227,9 @@ var Wolfronix = class {
227
227
  }
228
228
  if (includeAuth && this.token) {
229
229
  headers["Authorization"] = `Bearer ${this.token}`;
230
+ if (this.userId) {
231
+ headers["X-User-ID"] = this.userId;
232
+ }
230
233
  }
231
234
  return headers;
232
235
  }
@@ -459,57 +462,6 @@ var Wolfronix = class {
459
462
  formData
460
463
  });
461
464
  }
462
- /**
463
- * Encrypt a file using streaming (for large files)
464
- *
465
- * @example
466
- * ```typescript
467
- * const result = await wfx.encryptStream(largeFile, (progress) => {
468
- * console.log(`Progress: ${progress}%`);
469
- * });
470
- * ```
471
- */
472
- async encryptStream(file, onProgress) {
473
- this.ensureAuthenticated();
474
- const tokenResponse = await this.request("POST", "/api/v1/stream/token", {
475
- body: {
476
- user_id: this.userId,
477
- client_id: this.config.clientId
478
- }
479
- });
480
- const formData = new FormData();
481
- formData.append("file", file);
482
- formData.append("user_id", this.userId || "");
483
- formData.append("stream_token", tokenResponse.token);
484
- if (onProgress && typeof XMLHttpRequest !== "undefined") {
485
- return new Promise((resolve, reject) => {
486
- const xhr = new XMLHttpRequest();
487
- xhr.upload.onprogress = (event) => {
488
- if (event.lengthComputable) {
489
- onProgress(Math.round(event.loaded / event.total * 100));
490
- }
491
- };
492
- xhr.onload = () => {
493
- if (xhr.status >= 200 && xhr.status < 300) {
494
- resolve(JSON.parse(xhr.responseText));
495
- } else {
496
- reject(new WolfronixError("Upload failed", "UPLOAD_ERROR", xhr.status));
497
- }
498
- };
499
- xhr.onerror = () => reject(new NetworkError("Upload failed"));
500
- xhr.open("POST", `${this.config.baseUrl}/api/v1/stream/encrypt`);
501
- const headers = this.getHeaders();
502
- Object.entries(headers).forEach(([key, value]) => {
503
- xhr.setRequestHeader(key, value);
504
- });
505
- xhr.send(formData);
506
- });
507
- }
508
- return this.request("POST", "/api/v1/stream/encrypt", {
509
- formData
510
- // Stream endpoint might need update to accept public key too if re-implemented
511
- });
512
- }
513
465
  /**
514
466
  * Decrypt and retrieve a file
515
467
  *
@@ -533,9 +485,6 @@ var Wolfronix = class {
533
485
  throw new Error("Private key not available. Is user logged in?");
534
486
  }
535
487
  const privateKeyPEM = await exportKeyToPEM(this.privateKey, "private");
536
- const headers = this.getHeaders();
537
- headers["X-Private-Key"] = privateKeyPEM;
538
- headers["X-User-Role"] = "owner";
539
488
  return this.request("POST", `/api/v1/files/${fileId}/decrypt`, {
540
489
  responseType: "blob",
541
490
  headers: {
@@ -564,51 +513,6 @@ var Wolfronix = class {
564
513
  }
565
514
  });
566
515
  }
567
- /**
568
- * Decrypt using streaming (for large files)
569
- */
570
- async decryptStream(fileId, onProgress) {
571
- this.ensureAuthenticated();
572
- if (!fileId) {
573
- throw new ValidationError("File ID is required");
574
- }
575
- if (!this.privateKey) {
576
- throw new Error("Private key not available. Is user logged in?");
577
- }
578
- const privateKeyPEM = await exportKeyToPEM(this.privateKey, "private");
579
- if (onProgress && typeof XMLHttpRequest !== "undefined") {
580
- return new Promise((resolve, reject) => {
581
- const xhr = new XMLHttpRequest();
582
- xhr.responseType = "blob";
583
- xhr.onprogress = (event) => {
584
- if (event.lengthComputable) {
585
- onProgress(Math.round(event.loaded / event.total * 100));
586
- }
587
- };
588
- xhr.onload = () => {
589
- if (xhr.status >= 200 && xhr.status < 300) {
590
- resolve(xhr.response);
591
- } else {
592
- reject(new WolfronixError("Download failed", "DOWNLOAD_ERROR", xhr.status));
593
- }
594
- };
595
- xhr.onerror = () => reject(new NetworkError("Download failed"));
596
- xhr.open("POST", `${this.config.baseUrl}/api/v1/files/${fileId}/decrypt`);
597
- const headers = { ...this.getHeaders(), "X-Private-Key": privateKeyPEM, "X-User-Role": "owner" };
598
- Object.entries(headers).forEach(([key, value]) => {
599
- xhr.setRequestHeader(key, value);
600
- });
601
- xhr.send();
602
- });
603
- }
604
- return this.request("POST", `/api/v1/files/${fileId}/decrypt`, {
605
- responseType: "blob",
606
- headers: {
607
- "X-Private-Key": privateKeyPEM,
608
- "X-User-Role": "owner"
609
- }
610
- });
611
- }
612
516
  /**
613
517
  * List all encrypted files for current user
614
518
  *
@@ -620,7 +524,17 @@ var Wolfronix = class {
620
524
  */
621
525
  async listFiles() {
622
526
  this.ensureAuthenticated();
623
- return this.request("GET", "/api/v1/files");
527
+ const files = await this.request("GET", "/api/v1/files");
528
+ return {
529
+ success: true,
530
+ files: (files || []).map((f) => ({
531
+ file_id: f.id,
532
+ original_name: f.name,
533
+ encrypted_size: f.size_bytes,
534
+ created_at: f.date
535
+ })),
536
+ total: (files || []).length
537
+ };
624
538
  }
625
539
  /**
626
540
  * Delete an encrypted file
@@ -651,7 +565,7 @@ var Wolfronix = class {
651
565
  */
652
566
  async getMetrics() {
653
567
  this.ensureAuthenticated();
654
- return this.request("GET", "/api/v1/metrics");
568
+ return this.request("GET", "/api/v1/metrics/summary");
655
569
  }
656
570
  /**
657
571
  * Check if server is healthy
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wolfronix-sdk",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Official Wolfronix SDK for JavaScript/TypeScript - Zero-knowledge encryption made simple",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",