@time-file/browser-file-crypto 1.0.3 → 1.1.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.ko.md +43 -3
- package/README.md +43 -3
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +264 -7
- package/dist/index.mjs +388 -194
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
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 = {
|
|
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
|
|
13
|
+
class o 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,
|
|
21
|
-
super(
|
|
20
|
+
constructor(a, e) {
|
|
21
|
+
super(e ?? C[a]), this.name = "CryptoError", this.code = a, Error.captureStackTrace && Error.captureStackTrace(this, o);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
function
|
|
25
|
-
return n instanceof
|
|
24
|
+
function ue(n) {
|
|
25
|
+
return n instanceof o;
|
|
26
26
|
}
|
|
27
|
-
async function
|
|
27
|
+
async function w(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
|
|
32
|
+
throw new o("INVALID_INPUT");
|
|
33
33
|
}
|
|
34
|
-
function
|
|
34
|
+
function h(n) {
|
|
35
35
|
return n.buffer.slice(n.byteOffset, n.byteOffset + n.byteLength);
|
|
36
36
|
}
|
|
37
|
-
function
|
|
37
|
+
function Y(n) {
|
|
38
38
|
const a = new Uint8Array(n);
|
|
39
|
-
let
|
|
40
|
-
for (let
|
|
41
|
-
|
|
42
|
-
return btoa(
|
|
43
|
-
}
|
|
44
|
-
function
|
|
45
|
-
const a = atob(n),
|
|
46
|
-
for (let
|
|
47
|
-
t
|
|
48
|
-
return
|
|
49
|
-
}
|
|
50
|
-
async function
|
|
51
|
-
const
|
|
39
|
+
let e = "";
|
|
40
|
+
for (let t = 0; t < a.byteLength; t++)
|
|
41
|
+
e += String.fromCharCode(a[t]);
|
|
42
|
+
return btoa(e);
|
|
43
|
+
}
|
|
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);
|
|
48
|
+
return e.buffer;
|
|
49
|
+
}
|
|
50
|
+
async function T(n, a) {
|
|
51
|
+
const e = new TextEncoder(), t = await crypto.subtle.importKey(
|
|
52
52
|
"raw",
|
|
53
|
-
|
|
53
|
+
e.encode(n),
|
|
54
54
|
"PBKDF2",
|
|
55
55
|
!1,
|
|
56
56
|
["deriveKey"]
|
|
@@ -58,278 +58,472 @@ async function A(n, a) {
|
|
|
58
58
|
return crypto.subtle.deriveKey(
|
|
59
59
|
{
|
|
60
60
|
name: "PBKDF2",
|
|
61
|
-
salt:
|
|
61
|
+
salt: h(a),
|
|
62
62
|
iterations: 1e5,
|
|
63
|
-
hash:
|
|
63
|
+
hash: k
|
|
64
64
|
},
|
|
65
|
-
|
|
66
|
-
{ name:
|
|
65
|
+
t,
|
|
66
|
+
{ name: _, length: 256 },
|
|
67
67
|
!1,
|
|
68
68
|
// non-extractable for security
|
|
69
69
|
["encrypt", "decrypt"]
|
|
70
70
|
);
|
|
71
71
|
}
|
|
72
|
-
async function
|
|
72
|
+
async function I(n) {
|
|
73
73
|
try {
|
|
74
|
-
const a =
|
|
74
|
+
const a = O(n);
|
|
75
75
|
return await crypto.subtle.importKey(
|
|
76
76
|
"raw",
|
|
77
77
|
a,
|
|
78
|
-
{ name:
|
|
78
|
+
{ name: _, length: 256 },
|
|
79
79
|
!1,
|
|
80
80
|
// non-extractable for security
|
|
81
81
|
["encrypt", "decrypt"]
|
|
82
82
|
);
|
|
83
83
|
} catch {
|
|
84
|
-
throw new
|
|
84
|
+
throw new o("INVALID_KEYFILE");
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
-
function
|
|
87
|
+
function S(n) {
|
|
88
88
|
return crypto.getRandomValues(new Uint8Array(n));
|
|
89
89
|
}
|
|
90
|
-
function
|
|
91
|
-
return
|
|
90
|
+
function M() {
|
|
91
|
+
return S(16);
|
|
92
92
|
}
|
|
93
|
-
function
|
|
94
|
-
return
|
|
93
|
+
function N() {
|
|
94
|
+
return S(12);
|
|
95
95
|
}
|
|
96
|
-
const
|
|
97
|
-
function
|
|
98
|
-
const a = Math.max(8, Math.min(128, n)),
|
|
99
|
-
let
|
|
100
|
-
for (let
|
|
101
|
-
const c =
|
|
102
|
-
|
|
96
|
+
const L = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*", U = 16;
|
|
97
|
+
function ye(n = U) {
|
|
98
|
+
const a = Math.max(8, Math.min(128, n)), e = S(a);
|
|
99
|
+
let t = "";
|
|
100
|
+
for (let r = 0; r < a; r++) {
|
|
101
|
+
const c = e[r] % L.length;
|
|
102
|
+
t += L[c];
|
|
103
103
|
}
|
|
104
|
-
return
|
|
104
|
+
return t;
|
|
105
105
|
}
|
|
106
|
-
async function
|
|
107
|
-
const { password:
|
|
108
|
-
if (!
|
|
109
|
-
throw new
|
|
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
110
|
try {
|
|
111
|
-
|
|
112
|
-
const c = await
|
|
113
|
-
return
|
|
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
114
|
} catch (c) {
|
|
115
|
-
throw c instanceof
|
|
115
|
+
throw c instanceof o ? c : new o("ENCRYPTION_FAILED");
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
|
-
async function
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
const c = await
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
{ name:
|
|
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
125
|
c,
|
|
126
126
|
n
|
|
127
127
|
);
|
|
128
|
-
|
|
129
|
-
const
|
|
130
|
-
29 +
|
|
128
|
+
e == null || e({ phase: "encrypting", progress: 90 });
|
|
129
|
+
const s = new Uint8Array(
|
|
130
|
+
29 + i.byteLength
|
|
131
131
|
);
|
|
132
|
-
return
|
|
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
133
|
}
|
|
134
|
-
async function
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
const
|
|
138
|
-
|
|
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
139
|
const c = await crypto.subtle.encrypt(
|
|
140
|
-
{ name:
|
|
141
|
-
|
|
140
|
+
{ name: _, iv: h(t) },
|
|
141
|
+
r,
|
|
142
142
|
n
|
|
143
143
|
);
|
|
144
|
-
|
|
145
|
-
const
|
|
146
|
-
return
|
|
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
147
|
}
|
|
148
|
-
async function
|
|
149
|
-
const { password:
|
|
148
|
+
async function V(n, a) {
|
|
149
|
+
const { password: e, keyData: t, onProgress: r } = a;
|
|
150
150
|
try {
|
|
151
|
-
|
|
152
|
-
const c = new Uint8Array(await
|
|
153
|
-
if (
|
|
154
|
-
throw new
|
|
155
|
-
const
|
|
156
|
-
if (
|
|
157
|
-
if (!t)
|
|
158
|
-
throw new p("PASSWORD_REQUIRED");
|
|
159
|
-
return await b(c, t, i);
|
|
160
|
-
} else if (r === 2) {
|
|
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) {
|
|
161
157
|
if (!e)
|
|
162
|
-
throw new
|
|
163
|
-
return await
|
|
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
164
|
} else
|
|
165
|
-
throw new
|
|
165
|
+
throw new o("UNSUPPORTED_FORMAT");
|
|
166
166
|
} catch (c) {
|
|
167
|
-
throw c instanceof
|
|
167
|
+
throw c instanceof o ? c : new o("DECRYPTION_FAILED");
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
|
-
async function
|
|
170
|
+
async function v(n, a, e) {
|
|
171
171
|
if (n.length < 45)
|
|
172
|
-
throw new
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
|
|
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
176
|
try {
|
|
177
|
-
const
|
|
178
|
-
{ name:
|
|
179
|
-
|
|
177
|
+
const s = await crypto.subtle.decrypt(
|
|
178
|
+
{ name: _, iv: h(r) },
|
|
179
|
+
i,
|
|
180
180
|
c
|
|
181
181
|
);
|
|
182
|
-
return
|
|
182
|
+
return e == null || e({ phase: "complete", progress: 100 }), new Blob([s]);
|
|
183
183
|
} catch {
|
|
184
|
-
throw new
|
|
184
|
+
throw new o("INVALID_PASSWORD");
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
|
-
async function
|
|
187
|
+
async function G(n, a, e) {
|
|
188
188
|
if (n.length < 29)
|
|
189
|
-
throw new
|
|
190
|
-
|
|
191
|
-
const
|
|
192
|
-
|
|
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
193
|
try {
|
|
194
|
-
const
|
|
195
|
-
{ name:
|
|
194
|
+
const i = await crypto.subtle.decrypt(
|
|
195
|
+
{ name: _, iv: h(t) },
|
|
196
196
|
c,
|
|
197
|
-
|
|
197
|
+
r
|
|
198
198
|
);
|
|
199
|
-
return
|
|
199
|
+
return e == null || e({ phase: "complete", progress: 100 }), new Blob([i]);
|
|
200
200
|
} catch {
|
|
201
|
-
throw new
|
|
201
|
+
throw new o("INVALID_KEYFILE");
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function K(n, a) {
|
|
205
|
+
const e = new Uint8Array(12);
|
|
206
|
+
e.set(n);
|
|
207
|
+
const t = new DataView(e.buffer), r = t.getUint32(8, !0);
|
|
208
|
+
return t.setUint32(8, r ^ a, !0), e;
|
|
209
|
+
}
|
|
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;
|
|
213
|
+
}
|
|
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;
|
|
221
|
+
}
|
|
222
|
+
async function W(n, a, e, t) {
|
|
223
|
+
const r = K(e, t);
|
|
224
|
+
try {
|
|
225
|
+
const c = await crypto.subtle.decrypt(
|
|
226
|
+
{ name: _, iv: h(r) },
|
|
227
|
+
a,
|
|
228
|
+
h(n)
|
|
229
|
+
);
|
|
230
|
+
return new Uint8Array(c);
|
|
231
|
+
} catch {
|
|
232
|
+
throw new o("DECRYPTION_FAILED");
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function B(n, a, e, t) {
|
|
236
|
+
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;
|
|
239
|
+
} 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;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function g(n) {
|
|
245
|
+
const a = n[0], e = a === 17;
|
|
246
|
+
if (a !== 17 && a !== 18)
|
|
247
|
+
throw new o("UNSUPPORTED_FORMAT");
|
|
248
|
+
const t = n[1];
|
|
249
|
+
if (t !== 1)
|
|
250
|
+
throw new o("UNSUPPORTED_FORMAT");
|
|
251
|
+
const r = new DataView(n.buffer, n.byteOffset).getUint32(
|
|
252
|
+
2,
|
|
253
|
+
!0
|
|
254
|
+
);
|
|
255
|
+
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 };
|
|
258
|
+
} else {
|
|
259
|
+
const c = n.slice(6, 18);
|
|
260
|
+
return { isPassword: e, version: t, chunkSize: r, salt: null, baseIV: c, headerSize: 18 };
|
|
202
261
|
}
|
|
203
262
|
}
|
|
204
|
-
async function
|
|
205
|
-
const a
|
|
206
|
-
if (
|
|
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({
|
|
269
|
+
phase: "deriving_key",
|
|
270
|
+
processedBytes: 0,
|
|
271
|
+
processedChunks: 0
|
|
272
|
+
});
|
|
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;
|
|
275
|
+
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,
|
|
284
|
+
processedChunks: y
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
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++;
|
|
292
|
+
}
|
|
293
|
+
r == null || r({
|
|
294
|
+
phase: "complete",
|
|
295
|
+
processedBytes: R,
|
|
296
|
+
processedChunks: y,
|
|
297
|
+
progress: 100
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}), header: l };
|
|
301
|
+
}
|
|
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;
|
|
305
|
+
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");
|
|
316
|
+
t == null || t({
|
|
317
|
+
phase: "deriving_key",
|
|
318
|
+
processedBytes: 0,
|
|
319
|
+
processedChunks: 0
|
|
320
|
+
}), i = E ? await T(a, f.salt) : await I(e), r = r.slice(y), c = !0;
|
|
321
|
+
}
|
|
322
|
+
for (; r.length >= 4; ) {
|
|
323
|
+
const p = 4 + new DataView(
|
|
324
|
+
r.buffer,
|
|
325
|
+
r.byteOffset
|
|
326
|
+
).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",
|
|
333
|
+
processedBytes: l,
|
|
334
|
+
processedChunks: u
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
async flush() {
|
|
339
|
+
if (r.length > 0)
|
|
340
|
+
throw new o("INVALID_ENCRYPTED_DATA");
|
|
341
|
+
t == null || t({
|
|
342
|
+
phase: "complete",
|
|
343
|
+
processedBytes: l,
|
|
344
|
+
processedChunks: u,
|
|
345
|
+
progress: 100
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
async function fe(n, a) {
|
|
351
|
+
const e = n.size, t = a.onProgress ? (E) => {
|
|
352
|
+
a.onProgress({
|
|
353
|
+
...E,
|
|
354
|
+
totalBytes: e,
|
|
355
|
+
progress: E.phase === "complete" ? 100 : Math.round(E.processedBytes / e * 100)
|
|
356
|
+
});
|
|
357
|
+
} : void 0, { stream: r, header: c } = await x({
|
|
358
|
+
...a,
|
|
359
|
+
onProgress: t
|
|
360
|
+
}), s = n.stream().pipeThrough(r);
|
|
361
|
+
let u = !1;
|
|
362
|
+
const l = s.getReader();
|
|
363
|
+
return new ReadableStream({
|
|
364
|
+
async pull(E) {
|
|
365
|
+
if (!u) {
|
|
366
|
+
E.enqueue(c), u = !0;
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
try {
|
|
370
|
+
const { done: y, value: R } = await l.read();
|
|
371
|
+
y ? E.close() : E.enqueue(R);
|
|
372
|
+
} catch (y) {
|
|
373
|
+
E.error(y);
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
cancel() {
|
|
377
|
+
l.releaseLock();
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
function he(n, a) {
|
|
382
|
+
const e = z(a);
|
|
383
|
+
return n instanceof ReadableStream ? n.pipeThrough(e) : n.stream().pipeThrough(e);
|
|
384
|
+
}
|
|
385
|
+
async function Re(n) {
|
|
386
|
+
const a = await w(n), e = new Uint8Array(a);
|
|
387
|
+
if (e.length < 1)
|
|
207
388
|
return "unknown";
|
|
208
|
-
const
|
|
209
|
-
return
|
|
389
|
+
const t = e[0];
|
|
390
|
+
return t === 1 ? "password" : t === 2 ? "keyfile" : t === 17 ? "password-stream" : t === 18 ? "keyfile-stream" : "unknown";
|
|
210
391
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
392
|
+
const Q = 34, Z = 18;
|
|
393
|
+
async function _e(n) {
|
|
394
|
+
const a = await w(n), e = new Uint8Array(a);
|
|
395
|
+
if (e.length < 1)
|
|
214
396
|
return !1;
|
|
215
|
-
const
|
|
216
|
-
return
|
|
397
|
+
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;
|
|
217
399
|
}
|
|
218
|
-
function
|
|
219
|
-
|
|
400
|
+
function Ae(n) {
|
|
401
|
+
return n === "password-stream" || n === "keyfile-stream";
|
|
402
|
+
}
|
|
403
|
+
function de() {
|
|
404
|
+
const n = S(32);
|
|
220
405
|
return {
|
|
221
406
|
version: 1,
|
|
222
407
|
algorithm: "AES-256-GCM",
|
|
223
|
-
key:
|
|
408
|
+
key: Y(n.buffer),
|
|
224
409
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
225
410
|
};
|
|
226
411
|
}
|
|
227
|
-
function
|
|
412
|
+
function we(n) {
|
|
228
413
|
try {
|
|
229
414
|
const a = JSON.parse(n);
|
|
230
|
-
return
|
|
415
|
+
return q(a) ? a : null;
|
|
231
416
|
} catch {
|
|
232
417
|
return null;
|
|
233
418
|
}
|
|
234
419
|
}
|
|
235
|
-
function
|
|
420
|
+
function q(n) {
|
|
236
421
|
if (typeof n != "object" || n === null)
|
|
237
422
|
return !1;
|
|
238
423
|
const a = n;
|
|
239
424
|
return a.version === 1 && a.algorithm === "AES-256-GCM" && typeof a.key == "string" && a.key.length > 0 && typeof a.createdAt == "string";
|
|
240
425
|
}
|
|
241
|
-
function
|
|
242
|
-
const
|
|
426
|
+
function Te(n, a, e = "key") {
|
|
427
|
+
const t = {
|
|
243
428
|
version: 1,
|
|
244
429
|
algorithm: "AES-256-GCM",
|
|
245
430
|
key: n,
|
|
246
431
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
247
|
-
},
|
|
248
|
-
|
|
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);
|
|
249
434
|
}
|
|
250
|
-
async function
|
|
251
|
-
const a =
|
|
252
|
-
return Array.from(
|
|
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("");
|
|
253
438
|
}
|
|
254
|
-
async function
|
|
255
|
-
const { fileName:
|
|
439
|
+
async function Se(n, a) {
|
|
440
|
+
const { fileName: e, onProgress: t, ...r } = a;
|
|
256
441
|
try {
|
|
257
|
-
|
|
442
|
+
t == null || t({ phase: "downloading", progress: 0 });
|
|
258
443
|
const c = await fetch(n);
|
|
259
444
|
if (!c.ok)
|
|
260
|
-
throw new
|
|
445
|
+
throw new o(
|
|
261
446
|
"DOWNLOAD_FAILED",
|
|
262
447
|
`Download failed: ${c.status} ${c.statusText}`
|
|
263
448
|
);
|
|
264
|
-
const
|
|
265
|
-
let
|
|
266
|
-
|
|
449
|
+
const i = c.headers.get("content-length");
|
|
450
|
+
let s;
|
|
451
|
+
i && c.body ? s = await j(
|
|
267
452
|
c.body,
|
|
268
|
-
parseInt(
|
|
269
|
-
(
|
|
270
|
-
|
|
453
|
+
parseInt(i, 10),
|
|
454
|
+
(l) => {
|
|
455
|
+
t == null || t({ phase: "downloading", progress: Math.round(l * 50) });
|
|
271
456
|
}
|
|
272
|
-
) : (
|
|
273
|
-
const
|
|
274
|
-
...
|
|
275
|
-
onProgress: (
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
phase:
|
|
279
|
-
progress:
|
|
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,
|
|
460
|
+
onProgress: (l) => {
|
|
461
|
+
const E = 50 + Math.round(l.progress * 0.45);
|
|
462
|
+
t == null || t({
|
|
463
|
+
phase: l.phase === "complete" ? "complete" : l.phase,
|
|
464
|
+
progress: l.phase === "complete" ? 100 : E
|
|
280
465
|
});
|
|
281
466
|
}
|
|
282
467
|
});
|
|
283
|
-
|
|
468
|
+
$(u, e), t == null || t({ phase: "complete", progress: 100 });
|
|
284
469
|
} catch (c) {
|
|
285
|
-
throw c instanceof
|
|
470
|
+
throw c instanceof o ? c : new o("DOWNLOAD_FAILED");
|
|
286
471
|
}
|
|
287
472
|
}
|
|
288
|
-
async function
|
|
289
|
-
const
|
|
290
|
-
let c = 0,
|
|
291
|
-
for (; !
|
|
292
|
-
const
|
|
293
|
-
if (
|
|
294
|
-
|
|
295
|
-
const
|
|
296
|
-
|
|
473
|
+
async function j(n, a, e) {
|
|
474
|
+
const t = n.getReader(), r = [];
|
|
475
|
+
let c = 0, i = !1;
|
|
476
|
+
for (; !i; ) {
|
|
477
|
+
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));
|
|
297
482
|
}
|
|
298
483
|
}
|
|
299
|
-
const
|
|
300
|
-
let
|
|
301
|
-
for (const
|
|
302
|
-
|
|
303
|
-
return
|
|
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;
|
|
304
489
|
}
|
|
305
|
-
function
|
|
306
|
-
const
|
|
307
|
-
|
|
490
|
+
function $(n, a) {
|
|
491
|
+
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);
|
|
308
493
|
}
|
|
309
494
|
export {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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
|
|
334
528
|
};
|
|
335
529
|
//# sourceMappingURL=index.mjs.map
|