@time-file/browser-file-crypto 1.0.3 → 1.1.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.
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- const k = 16, G = 12, C = 256, U = 1e5, M = 32, v = 1, V = 2, B = 16, W = 45, x = 29, l = "AES-GCM", N = "SHA-256", T = {
1
+ const ne = 16, ae = 12, re = 256, ce = 1e5, se = 32, ie = 1, oe = 2, Ee = 17, le = 18, pe = 65536, ye = 1, ue = 16, de = 45, fe = 29, w = "AES-GCM", F = "SHA-256", Y = {
2
2
  INVALID_INPUT: "Input must be a File, Blob, or ArrayBuffer.",
3
3
  PASSWORD_REQUIRED: "Password or keyfile is required for encryption.",
4
4
  KEYFILE_REQUIRED: "Keyfile is required to decrypt this file.",
@@ -10,47 +10,47 @@ const k = 16, G = 12, C = 256, U = 1e5, M = 32, v = 1, V = 2, B = 16, W = 45, x
10
10
  DOWNLOAD_FAILED: "File download failed.",
11
11
  UNSUPPORTED_FORMAT: "Unsupported encryption format."
12
12
  };
13
- class p extends Error {
13
+ class E extends Error {
14
14
  /**
15
15
  * Creates a new CryptoError.
16
16
  *
17
17
  * @param code - Error code identifying the type of error
18
18
  * @param message - Optional custom message (defaults to predefined message)
19
19
  */
20
- constructor(a, t) {
21
- super(t ?? T[a]), this.name = "CryptoError", this.code = a, Error.captureStackTrace && Error.captureStackTrace(this, p);
20
+ constructor(r, e) {
21
+ super(e ?? Y[r]), this.name = "CryptoError", this.code = r, Error.captureStackTrace && Error.captureStackTrace(this, E);
22
22
  }
23
23
  }
24
- function j(n) {
25
- return n instanceof p;
24
+ function he(n) {
25
+ return n instanceof E;
26
26
  }
27
- async function s(n) {
27
+ async function S(n) {
28
28
  if (n instanceof ArrayBuffer)
29
29
  return n;
30
30
  if (n instanceof Blob)
31
31
  return n.arrayBuffer();
32
- throw new p("INVALID_INPUT");
32
+ throw new E("INVALID_INPUT");
33
33
  }
34
- function o(n) {
34
+ function R(n) {
35
35
  return n.buffer.slice(n.byteOffset, n.byteOffset + n.byteLength);
36
36
  }
37
- function L(n) {
38
- const a = new Uint8Array(n);
39
- let t = "";
40
- for (let e = 0; e < a.byteLength; e++)
41
- t += String.fromCharCode(a[e]);
42
- return btoa(t);
43
- }
44
- function _(n) {
45
- const a = atob(n), t = new Uint8Array(a.length);
46
- for (let e = 0; e < a.length; e++)
47
- t[e] = a.charCodeAt(e);
48
- return t.buffer;
49
- }
50
- async function A(n, a) {
51
- const t = new TextEncoder(), e = await crypto.subtle.importKey(
37
+ function U(n) {
38
+ const r = new Uint8Array(n);
39
+ let e = "";
40
+ for (let t = 0; t < r.byteLength; t++)
41
+ e += String.fromCharCode(r[t]);
42
+ return btoa(e);
43
+ }
44
+ function O(n) {
45
+ const r = atob(n), e = new Uint8Array(r.length);
46
+ for (let t = 0; t < r.length; t++)
47
+ e[t] = r.charCodeAt(t);
48
+ return e.buffer;
49
+ }
50
+ async function I(n, r) {
51
+ const e = new TextEncoder(), t = await crypto.subtle.importKey(
52
52
  "raw",
53
- t.encode(n),
53
+ e.encode(n),
54
54
  "PBKDF2",
55
55
  !1,
56
56
  ["deriveKey"]
@@ -58,278 +58,564 @@ async function A(n, a) {
58
58
  return crypto.subtle.deriveKey(
59
59
  {
60
60
  name: "PBKDF2",
61
- salt: o(a),
61
+ salt: R(r),
62
62
  iterations: 1e5,
63
- hash: N
63
+ hash: F
64
64
  },
65
- e,
66
- { name: l, length: 256 },
65
+ t,
66
+ { name: w, length: 256 },
67
67
  !1,
68
68
  // non-extractable for security
69
69
  ["encrypt", "decrypt"]
70
70
  );
71
71
  }
72
- async function w(n) {
72
+ async function T(n) {
73
73
  try {
74
- const a = _(n);
74
+ const r = O(n);
75
75
  return await crypto.subtle.importKey(
76
76
  "raw",
77
- a,
78
- { name: l, length: 256 },
77
+ r,
78
+ { name: w, length: 256 },
79
79
  !1,
80
80
  // non-extractable for security
81
81
  ["encrypt", "decrypt"]
82
82
  );
83
83
  } catch {
84
- throw new p("INVALID_KEYFILE");
84
+ throw new E("INVALID_KEYFILE");
85
85
  }
86
86
  }
87
- function u(n) {
87
+ function N(n) {
88
88
  return crypto.getRandomValues(new Uint8Array(n));
89
89
  }
90
- function R() {
91
- return u(16);
90
+ function b() {
91
+ return N(16);
92
92
  }
93
- function I() {
94
- return u(12);
93
+ function D() {
94
+ return N(12);
95
95
  }
96
- const h = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*", D = 16;
97
- function Z(n = D) {
98
- const a = Math.max(8, Math.min(128, n)), t = u(a);
99
- let e = "";
100
- for (let i = 0; i < a; i++) {
101
- const c = t[i] % h.length;
102
- e += h[c];
96
+ const L = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*", H = 16;
97
+ function Re(n = H) {
98
+ const r = Math.max(8, Math.min(128, n)), e = N(r);
99
+ let t = "";
100
+ for (let a = 0; a < r; a++) {
101
+ const c = e[a] % L.length;
102
+ t += L[c];
103
103
  }
104
- return e;
104
+ return t;
105
+ }
106
+ function M(n, r) {
107
+ const e = new Uint8Array(12);
108
+ e.set(n);
109
+ const t = new DataView(e.buffer), a = t.getUint32(8, !0);
110
+ return t.setUint32(8, a ^ r, !0), e;
105
111
  }
106
- async function Q(n, a) {
107
- const { password: t, keyData: e, onProgress: i } = a;
108
- if (!t && !e)
109
- throw new p("PASSWORD_REQUIRED");
112
+ function k(n, r) {
113
+ const e = new Uint8Array(n.length + r.length);
114
+ return e.set(n, 0), e.set(r, n.length), e;
115
+ }
116
+ async function m(n, r, e, t) {
117
+ const a = M(e, t), c = await crypto.subtle.encrypt(
118
+ { name: w, iv: R(a) },
119
+ r,
120
+ R(n)
121
+ ), s = new Uint8Array(4 + c.byteLength);
122
+ return new DataView(s.buffer).setUint32(0, c.byteLength, !0), s.set(new Uint8Array(c), 4), s;
123
+ }
124
+ async function V(n, r, e, t, a) {
125
+ const c = M(e, t);
110
126
  try {
111
- i == null || i({ phase: "deriving_key", progress: 0 });
112
- const c = await s(n);
113
- return i == null || i({ phase: "deriving_key", progress: 10 }), e ? await m(c, e, i) : await S(c, t, i);
127
+ const s = await crypto.subtle.decrypt(
128
+ { name: w, iv: R(c) },
129
+ r,
130
+ R(n)
131
+ );
132
+ return new Uint8Array(s);
133
+ } catch {
134
+ throw t === 0 ? new E(a ? "INVALID_PASSWORD" : "INVALID_KEYFILE") : new E("DECRYPTION_FAILED");
135
+ }
136
+ }
137
+ function v(n, r, e, t) {
138
+ if (n && e) {
139
+ const a = new Uint8Array(34);
140
+ return a[0] = 17, a[1] = 1, new DataView(a.buffer).setUint32(2, r, !0), a.set(e, 6), a.set(t, 22), a;
141
+ } else {
142
+ const a = new Uint8Array(18);
143
+ return a[0] = 18, a[1] = 1, new DataView(a.buffer).setUint32(2, r, !0), a.set(t, 6), a;
144
+ }
145
+ }
146
+ function B(n) {
147
+ const r = n[0], e = r === 17;
148
+ if (r !== 17 && r !== 18)
149
+ throw new E("UNSUPPORTED_FORMAT");
150
+ const t = n[1];
151
+ if (t !== 1)
152
+ throw new E("UNSUPPORTED_FORMAT");
153
+ const a = new DataView(n.buffer, n.byteOffset).getUint32(
154
+ 2,
155
+ !0
156
+ );
157
+ if (e) {
158
+ const c = n.slice(6, 22), s = n.slice(22, 34);
159
+ return { isPassword: e, version: t, chunkSize: a, salt: c, baseIV: s, headerSize: 34 };
160
+ } else {
161
+ const c = n.slice(6, 18);
162
+ return { isPassword: e, version: t, chunkSize: a, salt: null, baseIV: c, headerSize: 18 };
163
+ }
164
+ }
165
+ async function G(n) {
166
+ const { password: r, keyData: e, chunkSize: t = 65536, onProgress: a } = n;
167
+ if (!r && !e)
168
+ throw new E("PASSWORD_REQUIRED");
169
+ const c = !!r, s = c ? b() : null, i = D();
170
+ a == null || a({
171
+ phase: "deriving_key",
172
+ processedBytes: 0,
173
+ processedChunks: 0
174
+ });
175
+ const p = c ? await I(r, s) : await T(e), l = v(c, t, s, i);
176
+ let o = new Uint8Array(0), y = 0, u = 0;
177
+ return { stream: new TransformStream({
178
+ async transform(d, f) {
179
+ for (o = k(o, d); o.length >= t; ) {
180
+ const _ = o.slice(0, t);
181
+ o = o.slice(t);
182
+ const h = await m(_, p, i, y);
183
+ f.enqueue(h), y++, u += _.length, a == null || a({
184
+ phase: "encrypting",
185
+ processedBytes: u,
186
+ processedChunks: y
187
+ });
188
+ }
189
+ },
190
+ async flush(d) {
191
+ if (o.length > 0) {
192
+ const f = await m(o, p, i, y);
193
+ d.enqueue(f), u += o.length, y++;
194
+ }
195
+ a == null || a({
196
+ phase: "complete",
197
+ processedBytes: u,
198
+ processedChunks: y,
199
+ progress: 100
200
+ });
201
+ }
202
+ }), header: l };
203
+ }
204
+ function g(n) {
205
+ const { password: r, keyData: e, onProgress: t } = n;
206
+ let a = new Uint8Array(0), c = !1, s = null, i = null, p = 0, l = 0, o = !1, y = 0;
207
+ return new TransformStream({
208
+ async transform(u, A) {
209
+ if (a = k(a, u), !c) {
210
+ if (a.length < 2) return;
211
+ const f = a[0] === 17 ? 34 : 18;
212
+ if (a.length < f) return;
213
+ const _ = a.slice(0, f), h = B(_);
214
+ if (o = h.isPassword, i = h.baseIV, y = h.headerSize, o && !r)
215
+ throw new E("PASSWORD_REQUIRED");
216
+ if (!o && !e)
217
+ throw new E("KEYFILE_REQUIRED");
218
+ t == null || t({
219
+ phase: "deriving_key",
220
+ processedBytes: 0,
221
+ processedChunks: 0
222
+ }), s = o ? await I(r, h.salt) : await T(e), a = a.slice(y), c = !0;
223
+ }
224
+ for (; a.length >= 4; ) {
225
+ const f = 4 + new DataView(
226
+ a.buffer,
227
+ a.byteOffset
228
+ ).getUint32(0, !0);
229
+ if (a.length < f) break;
230
+ const _ = a.slice(4, f);
231
+ a = a.slice(f);
232
+ const h = await V(_, s, i, p, o);
233
+ A.enqueue(h), l += h.length, p++, t == null || t({
234
+ phase: "decrypting",
235
+ processedBytes: l,
236
+ processedChunks: p
237
+ });
238
+ }
239
+ },
240
+ async flush() {
241
+ if (a.length > 0)
242
+ throw new E("INVALID_ENCRYPTED_DATA");
243
+ t == null || t({
244
+ phase: "complete",
245
+ processedBytes: l,
246
+ processedChunks: p,
247
+ progress: 100
248
+ });
249
+ }
250
+ });
251
+ }
252
+ async function W(n, r) {
253
+ const e = n.size, t = r.onProgress ? (o) => {
254
+ r.onProgress({
255
+ ...o,
256
+ totalBytes: e,
257
+ progress: o.phase === "complete" ? 100 : Math.round(o.processedBytes / e * 100)
258
+ });
259
+ } : void 0, { stream: a, header: c } = await G({
260
+ ...r,
261
+ onProgress: t
262
+ }), i = n.stream().pipeThrough(a);
263
+ let p = !1;
264
+ const l = i.getReader();
265
+ return new ReadableStream({
266
+ async pull(o) {
267
+ if (!p) {
268
+ o.enqueue(c), p = !0;
269
+ return;
270
+ }
271
+ try {
272
+ const { done: y, value: u } = await l.read();
273
+ y ? o.close() : o.enqueue(u);
274
+ } catch (y) {
275
+ o.error(y);
276
+ }
277
+ },
278
+ cancel() {
279
+ l.releaseLock();
280
+ }
281
+ });
282
+ }
283
+ function K(n, r) {
284
+ const e = g(r);
285
+ return n instanceof ReadableStream ? n.pipeThrough(e) : n.stream().pipeThrough(e);
286
+ }
287
+ const x = 100 * 1024 * 1024;
288
+ async function z(n, r) {
289
+ const { password: e, keyData: t, onProgress: a } = r;
290
+ if (!e && !t)
291
+ throw new E("PASSWORD_REQUIRED");
292
+ try {
293
+ a == null || a({ phase: "deriving_key", progress: 0 });
294
+ const c = await S(n);
295
+ return a == null || a({ phase: "deriving_key", progress: 10 }), t ? await Q(c, t, a) : await P(c, e, a);
114
296
  } catch (c) {
115
- throw c instanceof p ? c : new p("ENCRYPTION_FAILED");
297
+ throw c instanceof E ? c : new E("ENCRYPTION_FAILED");
116
298
  }
117
299
  }
118
- async function S(n, a, t) {
119
- const e = R(), i = I();
120
- t == null || t({ phase: "deriving_key", progress: 20 });
121
- const c = await A(a, e);
122
- t == null || t({ phase: "encrypting", progress: 30 });
123
- const r = await crypto.subtle.encrypt(
124
- { name: l, iv: o(i) },
300
+ async function P(n, r, e) {
301
+ const t = b(), a = D();
302
+ e == null || e({ phase: "deriving_key", progress: 20 });
303
+ const c = await I(r, t);
304
+ e == null || e({ phase: "encrypting", progress: 30 });
305
+ const s = await crypto.subtle.encrypt(
306
+ { name: w, iv: R(a) },
125
307
  c,
126
308
  n
127
309
  );
128
- t == null || t({ phase: "encrypting", progress: 90 });
129
- const y = new Uint8Array(
130
- 29 + r.byteLength
310
+ e == null || e({ phase: "encrypting", progress: 90 });
311
+ const i = new Uint8Array(
312
+ 29 + s.byteLength
131
313
  );
132
- return y[0] = 1, y.set(e, 1), y.set(i, 17), y.set(new Uint8Array(r), 29), t == null || t({ phase: "complete", progress: 100 }), new Blob([y], { type: "application/octet-stream" });
314
+ return i[0] = 1, i.set(t, 1), i.set(a, 17), i.set(new Uint8Array(s), 29), e == null || e({ phase: "complete", progress: 100 }), new Blob([i], { type: "application/octet-stream" });
133
315
  }
134
- async function m(n, a, t) {
135
- const e = I();
136
- t == null || t({ phase: "deriving_key", progress: 20 });
137
- const i = await w(a);
138
- t == null || t({ phase: "encrypting", progress: 30 });
316
+ async function Q(n, r, e) {
317
+ const t = D();
318
+ e == null || e({ phase: "deriving_key", progress: 20 });
319
+ const a = await T(r);
320
+ e == null || e({ phase: "encrypting", progress: 30 });
139
321
  const c = await crypto.subtle.encrypt(
140
- { name: l, iv: o(e) },
141
- i,
322
+ { name: w, iv: R(t) },
323
+ a,
142
324
  n
143
325
  );
144
- t == null || t({ phase: "encrypting", progress: 90 });
145
- const r = new Uint8Array(13 + c.byteLength);
146
- return r[0] = 2, r.set(e, 1), r.set(new Uint8Array(c), 13), t == null || t({ phase: "complete", progress: 100 }), new Blob([r], { type: "application/octet-stream" });
326
+ e == null || e({ phase: "encrypting", progress: 90 });
327
+ const s = new Uint8Array(13 + c.byteLength);
328
+ return s[0] = 2, s.set(t, 1), s.set(new Uint8Array(c), 13), e == null || e({ phase: "complete", progress: 100 }), new Blob([s], { type: "application/octet-stream" });
147
329
  }
148
- async function O(n, a) {
149
- const { password: t, keyData: e, onProgress: i } = a;
330
+ async function we(n, r) {
331
+ const {
332
+ password: e,
333
+ keyData: t,
334
+ onProgress: a,
335
+ autoStreaming: c = !1,
336
+ streamingThreshold: s = x,
337
+ chunkSize: i = 65536
338
+ } = r;
339
+ if (!e && !t)
340
+ throw new E("PASSWORD_REQUIRED");
341
+ if (c && n.size > s) {
342
+ const o = await W(n, {
343
+ password: e,
344
+ keyData: t,
345
+ chunkSize: i,
346
+ onProgress: a ? (u) => {
347
+ a({
348
+ phase: u.phase,
349
+ progress: u.progress ?? Math.round(u.processedBytes / n.size * 100)
350
+ });
351
+ } : void 0
352
+ });
353
+ return await new Response(o).blob();
354
+ } else
355
+ return await z(n, { password: e, keyData: t, onProgress: a });
356
+ }
357
+ async function Z(n, r) {
358
+ const { password: e, keyData: t, onProgress: a } = r;
150
359
  try {
151
- i == null || i({ phase: "decrypting", progress: 0 });
152
- const c = new Uint8Array(await s(n));
153
- if (i == null || i({ phase: "decrypting", progress: 5 }), c.length < 1)
154
- throw new p("INVALID_ENCRYPTED_DATA");
155
- const r = c[0];
156
- if (r === 1) {
157
- if (!t)
158
- throw new p("PASSWORD_REQUIRED");
159
- return await b(c, t, i);
160
- } else if (r === 2) {
360
+ a == null || a({ phase: "decrypting", progress: 0 });
361
+ const c = new Uint8Array(await S(n));
362
+ if (a == null || a({ phase: "decrypting", progress: 5 }), c.length < 1)
363
+ throw new E("INVALID_ENCRYPTED_DATA");
364
+ const s = c[0];
365
+ if (s === 1) {
161
366
  if (!e)
162
- throw new p("KEYFILE_REQUIRED");
163
- return await K(c, e, i);
164
- } else
165
- throw new p("UNSUPPORTED_FORMAT");
367
+ throw new E("PASSWORD_REQUIRED");
368
+ return await q(c, e, a);
369
+ } else if (s === 2) {
370
+ if (!t)
371
+ throw new E("KEYFILE_REQUIRED");
372
+ return await j(c, t, a);
373
+ } else {
374
+ if (s === 17 || s === 18)
375
+ return await $(n, r);
376
+ throw new E("UNSUPPORTED_FORMAT");
377
+ }
166
378
  } catch (c) {
167
- throw c instanceof p ? c : new p("DECRYPTION_FAILED");
379
+ throw c instanceof E ? c : new E("DECRYPTION_FAILED");
168
380
  }
169
381
  }
170
- async function b(n, a, t) {
382
+ async function q(n, r, e) {
171
383
  if (n.length < 45)
172
- throw new p("INVALID_ENCRYPTED_DATA");
173
- t == null || t({ phase: "deriving_key", progress: 10 });
174
- const e = n.slice(1, 17), i = n.slice(17, 29), c = n.slice(29), r = await A(a, e);
175
- t == null || t({ phase: "decrypting", progress: 30 });
384
+ throw new E("INVALID_ENCRYPTED_DATA");
385
+ e == null || e({ phase: "deriving_key", progress: 10 });
386
+ const t = n.slice(1, 17), a = n.slice(17, 29), c = n.slice(29), s = await I(r, t);
387
+ e == null || e({ phase: "decrypting", progress: 30 });
176
388
  try {
177
- const y = await crypto.subtle.decrypt(
178
- { name: l, iv: o(i) },
179
- r,
389
+ const i = await crypto.subtle.decrypt(
390
+ { name: w, iv: R(a) },
391
+ s,
180
392
  c
181
393
  );
182
- return t == null || t({ phase: "complete", progress: 100 }), new Blob([y]);
394
+ return e == null || e({ phase: "complete", progress: 100 }), new Blob([i]);
183
395
  } catch {
184
- throw new p("INVALID_PASSWORD");
396
+ throw new E("INVALID_PASSWORD");
185
397
  }
186
398
  }
187
- async function K(n, a, t) {
399
+ async function j(n, r, e) {
188
400
  if (n.length < 29)
189
- throw new p("INVALID_ENCRYPTED_DATA");
190
- t == null || t({ phase: "decrypting", progress: 10 });
191
- const e = n.slice(1, 13), i = n.slice(13), c = await w(a);
192
- t == null || t({ phase: "decrypting", progress: 30 });
401
+ throw new E("INVALID_ENCRYPTED_DATA");
402
+ e == null || e({ phase: "decrypting", progress: 10 });
403
+ const t = n.slice(1, 13), a = n.slice(13), c = await T(r);
404
+ e == null || e({ phase: "decrypting", progress: 30 });
193
405
  try {
194
- const r = await crypto.subtle.decrypt(
195
- { name: l, iv: o(e) },
406
+ const s = await crypto.subtle.decrypt(
407
+ { name: w, iv: R(t) },
196
408
  c,
197
- i
409
+ a
198
410
  );
199
- return t == null || t({ phase: "complete", progress: 100 }), new Blob([r]);
411
+ return e == null || e({ phase: "complete", progress: 100 }), new Blob([s]);
200
412
  } catch {
201
- throw new p("INVALID_KEYFILE");
413
+ throw new E("INVALID_KEYFILE");
202
414
  }
203
415
  }
204
- async function g(n) {
205
- const a = await s(n), t = new Uint8Array(a);
206
- if (t.length < 1)
416
+ async function $(n, r) {
417
+ const { password: e, keyData: t, onProgress: a } = r, c = n instanceof Blob ? n : new Blob([n]), i = K(c, {
418
+ password: e,
419
+ keyData: t,
420
+ onProgress: a ? (l) => {
421
+ a({
422
+ phase: l.phase,
423
+ progress: l.progress ?? Math.round(l.processedBytes / (l.totalBytes || 1) * 100)
424
+ });
425
+ } : void 0
426
+ });
427
+ return await new Response(i).blob();
428
+ }
429
+ async function _e(n) {
430
+ const r = await S(n), e = new Uint8Array(r);
431
+ if (e.length < 1)
207
432
  return "unknown";
208
- const e = t[0];
209
- return e === 1 ? "password" : e === 2 ? "keyfile" : "unknown";
433
+ const t = e[0];
434
+ return t === 1 ? "password" : t === 2 ? "keyfile" : t === 17 ? "password-stream" : t === 18 ? "keyfile-stream" : "unknown";
210
435
  }
211
- async function $(n) {
212
- const a = await s(n), t = new Uint8Array(a);
213
- if (t.length < 1)
436
+ const J = 34, X = 18;
437
+ async function Ae(n) {
438
+ const r = await S(n), e = new Uint8Array(r);
439
+ if (e.length < 1)
214
440
  return !1;
215
- const e = t[0];
216
- return e === 1 && t.length >= 45 || e === 2 && t.length >= 29;
441
+ const t = e[0];
442
+ return t === 1 && e.length >= 45 || t === 2 && e.length >= 29 || t === 17 && e.length >= J || t === 18 && e.length >= X;
443
+ }
444
+ function Se(n) {
445
+ return n === "password-stream" || n === "keyfile-stream";
217
446
  }
218
- function q() {
219
- const n = u(32);
447
+ function Ie() {
448
+ const n = N(32);
220
449
  return {
221
450
  version: 1,
222
451
  algorithm: "AES-256-GCM",
223
- key: L(n.buffer),
452
+ key: U(n.buffer),
224
453
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
225
454
  };
226
455
  }
227
- function J(n) {
456
+ function Te(n) {
228
457
  try {
229
- const a = JSON.parse(n);
230
- return Y(a) ? a : null;
458
+ const r = JSON.parse(n);
459
+ return ee(r) ? r : null;
231
460
  } catch {
232
461
  return null;
233
462
  }
234
463
  }
235
- function Y(n) {
464
+ function ee(n) {
236
465
  if (typeof n != "object" || n === null)
237
466
  return !1;
238
- const a = n;
239
- return a.version === 1 && a.algorithm === "AES-256-GCM" && typeof a.key == "string" && a.key.length > 0 && typeof a.createdAt == "string";
467
+ const r = n;
468
+ return r.version === 1 && r.algorithm === "AES-256-GCM" && typeof r.key == "string" && r.key.length > 0 && typeof r.createdAt == "string";
240
469
  }
241
- function z(n, a, t = "key") {
242
- const e = {
470
+ function Ne(n, r, e = "key") {
471
+ const t = {
243
472
  version: 1,
244
473
  algorithm: "AES-256-GCM",
245
474
  key: n,
246
475
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
247
- }, i = JSON.stringify(e, null, 2), c = new Blob([i], { type: "application/json" }), r = URL.createObjectURL(c), y = document.createElement("a");
248
- y.href = r, y.download = `${a}.${t}`, y.style.display = "none", document.body.appendChild(y), y.click(), document.body.removeChild(y), URL.revokeObjectURL(r);
476
+ }, a = JSON.stringify(t, null, 2), c = new Blob([a], { type: "application/json" }), s = URL.createObjectURL(c), i = document.createElement("a");
477
+ i.href = s, i.download = `${r}.${e}`, i.style.display = "none", document.body.appendChild(i), i.click(), document.body.removeChild(i), URL.revokeObjectURL(s);
249
478
  }
250
- async function X(n) {
251
- const a = _(n), t = await crypto.subtle.digest("SHA-256", a), e = new Uint8Array(t);
252
- return Array.from(e).map((i) => i.toString(16).padStart(2, "0")).join("");
479
+ async function De(n) {
480
+ const r = O(n), e = await crypto.subtle.digest("SHA-256", r), t = new Uint8Array(e);
481
+ return Array.from(t).map((a) => a.toString(16).padStart(2, "0")).join("");
253
482
  }
254
- async function P(n, a) {
255
- const { fileName: t, onProgress: e, ...i } = a;
483
+ async function Le(n, r) {
484
+ const { fileName: e, onProgress: t, ...a } = r;
256
485
  try {
257
- e == null || e({ phase: "downloading", progress: 0 });
486
+ t == null || t({ phase: "downloading", progress: 0 });
258
487
  const c = await fetch(n);
259
488
  if (!c.ok)
260
- throw new p(
489
+ throw new E(
261
490
  "DOWNLOAD_FAILED",
262
491
  `Download failed: ${c.status} ${c.statusText}`
263
492
  );
264
- const r = c.headers.get("content-length");
265
- let y;
266
- r && c.body ? y = await F(
493
+ const s = c.headers.get("content-length");
494
+ let i;
495
+ s && c.body ? i = await te(
267
496
  c.body,
268
- parseInt(r, 10),
269
- (E) => {
270
- e == null || e({ phase: "downloading", progress: Math.round(E * 50) });
497
+ parseInt(s, 10),
498
+ (l) => {
499
+ t == null || t({ phase: "downloading", progress: Math.round(l * 50) });
271
500
  }
272
- ) : (e == null || e({ phase: "downloading", progress: 25 }), y = await c.arrayBuffer()), e == null || e({ phase: "downloading", progress: 50 });
273
- const f = await O(y, {
274
- ...i,
275
- onProgress: (E) => {
276
- const d = 50 + Math.round(E.progress * 0.45);
277
- e == null || e({
278
- phase: E.phase === "complete" ? "complete" : E.phase,
279
- progress: E.phase === "complete" ? 100 : d
501
+ ) : (t == null || t({ phase: "downloading", progress: 25 }), i = await c.arrayBuffer()), t == null || t({ phase: "downloading", progress: 50 });
502
+ const p = await Z(i, {
503
+ ...a,
504
+ onProgress: (l) => {
505
+ const o = 50 + Math.round(l.progress * 0.45);
506
+ t == null || t({
507
+ phase: l.phase === "complete" ? "complete" : l.phase,
508
+ progress: l.phase === "complete" ? 100 : o
280
509
  });
281
510
  }
282
511
  });
283
- H(f, t), e == null || e({ phase: "complete", progress: 100 });
512
+ C(p, e), t == null || t({ phase: "complete", progress: 100 });
284
513
  } catch (c) {
285
- throw c instanceof p ? c : new p("DOWNLOAD_FAILED");
514
+ throw c instanceof E ? c : new E("DOWNLOAD_FAILED");
286
515
  }
287
516
  }
288
- async function F(n, a, t) {
289
- const e = n.getReader(), i = [];
290
- let c = 0, r = !1;
291
- for (; !r; ) {
292
- const E = await e.read();
293
- if (r = E.done, E.value) {
294
- i.push(E.value), c += E.value.length;
295
- const d = c / a;
296
- t(Math.min(d, 1));
517
+ async function te(n, r, e) {
518
+ const t = n.getReader(), a = [];
519
+ let c = 0, s = !1;
520
+ for (; !s; ) {
521
+ const l = await t.read();
522
+ if (s = l.done, l.value) {
523
+ a.push(l.value), c += l.value.length;
524
+ const o = c / r;
525
+ e(Math.min(o, 1));
297
526
  }
298
527
  }
299
- const y = new Uint8Array(c);
300
- let f = 0;
301
- for (const E of i)
302
- y.set(E, f), f += E.length;
303
- return y.buffer;
528
+ const i = new Uint8Array(c);
529
+ let p = 0;
530
+ for (const l of a)
531
+ i.set(l, p), p += l.length;
532
+ return i.buffer;
304
533
  }
305
- function H(n, a) {
306
- const t = URL.createObjectURL(n), e = document.createElement("a");
307
- e.href = t, e.download = a, e.style.display = "none", document.body.appendChild(e), e.click(), document.body.removeChild(e), URL.revokeObjectURL(t);
534
+ function C(n, r) {
535
+ const e = URL.createObjectURL(n), t = document.createElement("a");
536
+ t.href = e, t.download = r, t.style.display = "none", document.body.appendChild(t), t.click(), document.body.removeChild(t), URL.revokeObjectURL(e);
537
+ }
538
+ async function me(n, r) {
539
+ const { fileName: e, password: t, keyData: a, onProgress: c } = r;
540
+ try {
541
+ c == null || c({
542
+ phase: "downloading",
543
+ processedBytes: 0,
544
+ processedChunks: 0,
545
+ progress: 0
546
+ });
547
+ const s = await fetch(n);
548
+ if (!s.ok)
549
+ throw new E(
550
+ "DOWNLOAD_FAILED",
551
+ `Download failed: ${s.status} ${s.statusText}`
552
+ );
553
+ const i = s.headers.get("content-length"), p = i ? parseInt(i, 10) : void 0;
554
+ c == null || c({
555
+ phase: "downloading",
556
+ processedBytes: 0,
557
+ processedChunks: 0,
558
+ totalBytes: p,
559
+ progress: 25
560
+ });
561
+ const l = await s.blob();
562
+ let o = 0;
563
+ const y = K(l, {
564
+ password: t,
565
+ keyData: a,
566
+ onProgress: (d) => {
567
+ o = d.processedBytes, c == null || c({
568
+ ...d,
569
+ // Map to 50-95% range
570
+ progress: d.phase === "complete" ? 100 : 50 + Math.round((d.progress ?? 0) * 0.45)
571
+ });
572
+ }
573
+ }), A = await new Response(y).blob();
574
+ C(A, e), c == null || c({
575
+ phase: "complete",
576
+ processedBytes: o,
577
+ processedChunks: 0,
578
+ progress: 100
579
+ });
580
+ } catch (s) {
581
+ throw s instanceof E ? s : new E("DOWNLOAD_FAILED");
582
+ }
308
583
  }
309
584
  export {
310
- l as ALGORITHM,
311
- B as AUTH_TAG_LENGTH,
312
- p as CryptoError,
313
- V as ENCRYPTION_MARKER_KEYFILE,
314
- v as ENCRYPTION_MARKER_PASSWORD,
315
- N as HASH_ALGORITHM,
316
- G as IV_LENGTH,
317
- M as KEYFILE_KEY_LENGTH,
318
- C as KEY_LENGTH,
319
- x as MIN_ENCRYPTED_SIZE_KEYFILE,
320
- W as MIN_ENCRYPTED_SIZE_PASSWORD,
321
- U as PBKDF2_ITERATIONS,
322
- k as SALT_LENGTH,
323
- X as computeKeyFileHash,
324
- O as decryptFile,
325
- P as downloadAndDecrypt,
326
- z as downloadKeyFile,
327
- Q as encryptFile,
328
- q as generateKeyFile,
329
- Z as generateRandomPassword,
330
- g as getEncryptionType,
331
- j as isCryptoError,
332
- $ as isEncryptedFile,
333
- J as parseKeyFile
585
+ w as ALGORITHM,
586
+ ue as AUTH_TAG_LENGTH,
587
+ E as CryptoError,
588
+ pe as DEFAULT_CHUNK_SIZE,
589
+ oe as ENCRYPTION_MARKER_KEYFILE,
590
+ le as ENCRYPTION_MARKER_KEYFILE_STREAM,
591
+ ie as ENCRYPTION_MARKER_PASSWORD,
592
+ Ee as ENCRYPTION_MARKER_PASSWORD_STREAM,
593
+ F as HASH_ALGORITHM,
594
+ ae as IV_LENGTH,
595
+ se as KEYFILE_KEY_LENGTH,
596
+ re as KEY_LENGTH,
597
+ fe as MIN_ENCRYPTED_SIZE_KEYFILE,
598
+ de as MIN_ENCRYPTED_SIZE_PASSWORD,
599
+ ce as PBKDF2_ITERATIONS,
600
+ ne as SALT_LENGTH,
601
+ ye as STREAM_FORMAT_VERSION,
602
+ De as computeKeyFileHash,
603
+ g as createDecryptStream,
604
+ G as createEncryptStream,
605
+ Z as decryptFile,
606
+ K as decryptFileStream,
607
+ Le as downloadAndDecrypt,
608
+ me as downloadAndDecryptStream,
609
+ Ne as downloadKeyFile,
610
+ z as encryptFile,
611
+ we as encryptFileAuto,
612
+ W as encryptFileStream,
613
+ Ie as generateKeyFile,
614
+ Re as generateRandomPassword,
615
+ _e as getEncryptionType,
616
+ he as isCryptoError,
617
+ Ae as isEncryptedFile,
618
+ Se as isStreamingEncryption,
619
+ Te as parseKeyFile
334
620
  };
335
621
  //# sourceMappingURL=index.mjs.map