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