cipher-kit 2.0.0 → 2.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.md +25 -27
- package/dist/{chunk-3UX5MZ2P.cjs → chunk-BHG5RSUV.cjs} +22 -20
- package/dist/chunk-BHG5RSUV.cjs.map +1 -0
- package/dist/{chunk-4MFF6V3R.js → chunk-CRTOKS3Q.js} +76 -41
- package/dist/chunk-CRTOKS3Q.js.map +1 -0
- package/dist/{chunk-N2EW2FDZ.cjs → chunk-HMTHK2IY.cjs} +183 -148
- package/dist/chunk-HMTHK2IY.cjs.map +1 -0
- package/dist/{chunk-ACFPMIXO.js → chunk-RAEBT46G.js} +75 -40
- package/dist/chunk-RAEBT46G.js.map +1 -0
- package/dist/{chunk-FKSYSPJR.js → chunk-RUTGDMVR.js} +21 -20
- package/dist/chunk-RUTGDMVR.js.map +1 -0
- package/dist/{chunk-CVCDAHDW.cjs → chunk-UVEMRK5F.cjs} +189 -154
- package/dist/chunk-UVEMRK5F.cjs.map +1 -0
- package/dist/{export-BMvZq46v.d.ts → export-5hmOiU0J.d.cts} +194 -20
- package/dist/{export-CQNsJFh_.d.cts → export-BF9wW56f.d.ts} +194 -20
- package/dist/{export-llM6c7Do.d.ts → export-DVERZibl.d.cts} +194 -20
- package/dist/{export-55tHE0Bw.d.cts → export-w8sBcKXw.d.ts} +194 -20
- package/dist/index.cjs +12 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/node.cjs +33 -33
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +2 -2
- package/dist/{validate-EHuJC5QQ.d.cts → validate-B3uHoP8n.d.cts} +26 -38
- package/dist/{validate-EHuJC5QQ.d.ts → validate-B3uHoP8n.d.ts} +26 -38
- package/dist/web-api.cjs +33 -33
- package/dist/web-api.d.cts +2 -2
- package/dist/web-api.d.ts +2 -2
- package/dist/web-api.js +2 -2
- package/package.json +6 -7
- package/dist/chunk-3UX5MZ2P.cjs.map +0 -1
- package/dist/chunk-4MFF6V3R.js.map +0 -1
- package/dist/chunk-ACFPMIXO.js.map +0 -1
- package/dist/chunk-CVCDAHDW.cjs.map +0 -1
- package/dist/chunk-FKSYSPJR.js.map +0 -1
- package/dist/chunk-N2EW2FDZ.cjs.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkBHG5RSUV_cjs = require('./chunk-BHG5RSUV.cjs');
|
|
4
4
|
|
|
5
5
|
// src/web/kit.ts
|
|
6
6
|
var kit_exports = {};
|
|
7
|
-
|
|
7
|
+
chunkBHG5RSUV_cjs.__export(kit_exports, {
|
|
8
8
|
convertBytesToStr: () => convertBytesToStr,
|
|
9
9
|
convertEncoding: () => convertEncoding,
|
|
10
10
|
convertStrToBytes: () => convertStrToBytes,
|
|
@@ -35,34 +35,34 @@ chunk3UX5MZ2P_cjs.__export(kit_exports, {
|
|
|
35
35
|
var textEncoder = new TextEncoder();
|
|
36
36
|
var textDecoder = new TextDecoder();
|
|
37
37
|
function $convertStrToBytes(data, inputEncoding = "utf8") {
|
|
38
|
-
if (!
|
|
39
|
-
return
|
|
38
|
+
if (!chunkBHG5RSUV_cjs.$isStr(data)) {
|
|
39
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
40
40
|
msg: "Crypto Web API - String to Bytes: Empty data",
|
|
41
41
|
desc: "Data must be a non-empty string"
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
|
-
if (!
|
|
45
|
-
return
|
|
44
|
+
if (!chunkBHG5RSUV_cjs.ENCODING.includes(inputEncoding)) {
|
|
45
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
46
46
|
msg: `Crypto Web API - String to Bytes: Unsupported encoding: ${inputEncoding}`,
|
|
47
47
|
desc: "Use base64, base64url, hex, utf8, or latin1"
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
try {
|
|
51
51
|
const bytes = strToBytes[inputEncoding](data);
|
|
52
|
-
return
|
|
52
|
+
return chunkBHG5RSUV_cjs.$ok({ result: bytes });
|
|
53
53
|
} catch (error) {
|
|
54
|
-
return
|
|
54
|
+
return chunkBHG5RSUV_cjs.$err({ msg: "Crypto Web API - String to Bytes: Failed to convert data", desc: chunkBHG5RSUV_cjs.$fmtError(error) });
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
function $convertBytesToStr(data, outputEncoding = "utf8") {
|
|
58
58
|
if (!(data instanceof ArrayBuffer || data instanceof Uint8Array)) {
|
|
59
|
-
return
|
|
59
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
60
60
|
msg: "Crypto Web API - Bytes to String: Invalid data type",
|
|
61
61
|
desc: "Data must be an ArrayBuffer or Uint8Array"
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
|
-
if (!
|
|
65
|
-
return
|
|
64
|
+
if (!chunkBHG5RSUV_cjs.ENCODING.includes(outputEncoding)) {
|
|
65
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
66
66
|
msg: `Crypto Web API - Bytes to String: Unsupported encoding: ${outputEncoding}`,
|
|
67
67
|
desc: "Use base64, base64url, hex, utf8, or latin1"
|
|
68
68
|
});
|
|
@@ -70,29 +70,29 @@ function $convertBytesToStr(data, outputEncoding = "utf8") {
|
|
|
70
70
|
try {
|
|
71
71
|
const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
72
72
|
const str = bytesToStr[outputEncoding](bytes);
|
|
73
|
-
return
|
|
73
|
+
return chunkBHG5RSUV_cjs.$ok(str);
|
|
74
74
|
} catch (error) {
|
|
75
|
-
return
|
|
75
|
+
return chunkBHG5RSUV_cjs.$err({ msg: "Crypto Web API - Bytes to String: Failed to convert data", desc: chunkBHG5RSUV_cjs.$fmtError(error) });
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
function $convertEncoding(data, from, to) {
|
|
79
|
-
if (!
|
|
80
|
-
return
|
|
79
|
+
if (!chunkBHG5RSUV_cjs.$isStr(data)) {
|
|
80
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
81
81
|
msg: "Crypto Web API - Convert Format: Empty data",
|
|
82
82
|
desc: "Data must be a non-empty string"
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
|
-
if (!
|
|
86
|
-
return
|
|
85
|
+
if (!chunkBHG5RSUV_cjs.ENCODING.includes(from) || !chunkBHG5RSUV_cjs.ENCODING.includes(to)) {
|
|
86
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
87
87
|
msg: `Crypto Web API - Convert Format: Unsupported encoding: from ${from} to ${to}`,
|
|
88
88
|
desc: "Use base64, base64url, hex, utf8, or latin1"
|
|
89
89
|
});
|
|
90
90
|
}
|
|
91
91
|
const bytes = $convertStrToBytes(data, from);
|
|
92
|
-
if (bytes.error) return
|
|
92
|
+
if (bytes.error) return chunkBHG5RSUV_cjs.$err({ msg: bytes.error.message, desc: bytes.error.description });
|
|
93
93
|
const str = $convertBytesToStr(bytes.result, to);
|
|
94
|
-
if (str.error) return
|
|
95
|
-
return
|
|
94
|
+
if (str.error) return chunkBHG5RSUV_cjs.$err({ msg: str.error.message, desc: str.error.description });
|
|
95
|
+
return chunkBHG5RSUV_cjs.$ok({ result: str.result });
|
|
96
96
|
}
|
|
97
97
|
var strToBytes = {
|
|
98
98
|
base64: $fromBase64,
|
|
@@ -158,45 +158,54 @@ function $fromHex(data) {
|
|
|
158
158
|
// src/web/web-encrypt.ts
|
|
159
159
|
function $generateUuid() {
|
|
160
160
|
try {
|
|
161
|
-
return
|
|
161
|
+
return chunkBHG5RSUV_cjs.$ok(crypto.randomUUID());
|
|
162
162
|
} catch (error) {
|
|
163
|
-
return
|
|
163
|
+
return chunkBHG5RSUV_cjs.$err({ msg: `${chunkBHG5RSUV_cjs.title("web", "UUID Generation")}: Failed to generate UUID`, desc: chunkBHG5RSUV_cjs.$fmtError(error) });
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
-
async function $createSecretKey(secret, options
|
|
167
|
-
if (!
|
|
168
|
-
return
|
|
166
|
+
async function $createSecretKey(secret, options) {
|
|
167
|
+
if (!chunkBHG5RSUV_cjs.$isStr(secret, 8)) {
|
|
168
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
169
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Key Generation")}: Empty Secret`,
|
|
170
|
+
desc: "Secret must be a non-empty string with at least 8 characters"
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
if (!chunkBHG5RSUV_cjs.$isPlainObj(options)) {
|
|
174
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
175
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Key Generation")}: Invalid options`,
|
|
176
|
+
desc: "Options must be an object"
|
|
177
|
+
});
|
|
169
178
|
}
|
|
170
179
|
const algorithm = options.algorithm ?? "aes256gcm";
|
|
171
|
-
if (!(algorithm in
|
|
172
|
-
return
|
|
173
|
-
msg: `${
|
|
174
|
-
desc: `Supported algorithms are: ${Object.keys(
|
|
180
|
+
if (!(algorithm in chunkBHG5RSUV_cjs.ENCRYPTION_ALGORITHMS)) {
|
|
181
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
182
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Key Generation")}: Unsupported algorithm: ${algorithm}`,
|
|
183
|
+
desc: `Supported algorithms are: ${Object.keys(chunkBHG5RSUV_cjs.ENCRYPTION_ALGORITHMS).join(", ")}`
|
|
175
184
|
});
|
|
176
185
|
}
|
|
177
186
|
const digest = options.digest ?? "sha256";
|
|
178
|
-
if (!(digest in
|
|
179
|
-
return
|
|
180
|
-
msg: `${
|
|
181
|
-
desc: `Supported digests are: ${Object.keys(
|
|
187
|
+
if (!(digest in chunkBHG5RSUV_cjs.DIGEST_ALGORITHMS)) {
|
|
188
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
189
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Key Generation")}: Unsupported digest: ${digest}`,
|
|
190
|
+
desc: `Supported digests are: ${Object.keys(chunkBHG5RSUV_cjs.DIGEST_ALGORITHMS).join(", ")}`
|
|
182
191
|
});
|
|
183
192
|
}
|
|
184
193
|
const salt = options.salt ?? "cipher-kit-salt";
|
|
185
|
-
if (!
|
|
186
|
-
return
|
|
187
|
-
msg: `${
|
|
194
|
+
if (!chunkBHG5RSUV_cjs.$isStr(salt, 8)) {
|
|
195
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
196
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Key Generation")}: Weak salt`,
|
|
188
197
|
desc: "Salt must be a non-empty string with at least 8 characters"
|
|
189
198
|
});
|
|
190
199
|
}
|
|
191
200
|
const info = options.info ?? "cipher-kit";
|
|
192
|
-
if (!
|
|
193
|
-
return
|
|
194
|
-
msg: `${
|
|
201
|
+
if (!chunkBHG5RSUV_cjs.$isStr(info)) {
|
|
202
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
203
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Key Generation")}: Invalid info`,
|
|
195
204
|
desc: "Info must be a non-empty string"
|
|
196
205
|
});
|
|
197
206
|
}
|
|
198
|
-
const encryptAlgo =
|
|
199
|
-
const digestAlgo =
|
|
207
|
+
const encryptAlgo = chunkBHG5RSUV_cjs.ENCRYPTION_ALGORITHMS[algorithm];
|
|
208
|
+
const digestAlgo = chunkBHG5RSUV_cjs.DIGEST_ALGORITHMS[digest];
|
|
200
209
|
try {
|
|
201
210
|
const ikm = await crypto.subtle.importKey("raw", textEncoder.encode(secret.normalize("NFKC")), "HKDF", false, [
|
|
202
211
|
"deriveKey"
|
|
@@ -219,37 +228,43 @@ async function $createSecretKey(secret, options = {}) {
|
|
|
219
228
|
algorithm,
|
|
220
229
|
key
|
|
221
230
|
});
|
|
222
|
-
return
|
|
231
|
+
return chunkBHG5RSUV_cjs.$ok({ result: secretKey });
|
|
223
232
|
} catch (error) {
|
|
224
|
-
return
|
|
225
|
-
msg: `${
|
|
226
|
-
desc:
|
|
233
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
234
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Key Generation")}: Failed to create secret key`,
|
|
235
|
+
desc: chunkBHG5RSUV_cjs.$fmtError(error)
|
|
227
236
|
});
|
|
228
237
|
}
|
|
229
238
|
}
|
|
230
|
-
async function $encrypt(data, secretKey, options
|
|
231
|
-
if (!
|
|
232
|
-
return
|
|
233
|
-
msg: `${
|
|
239
|
+
async function $encrypt(data, secretKey, options) {
|
|
240
|
+
if (!chunkBHG5RSUV_cjs.$isStr(data)) {
|
|
241
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
242
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Encryption")}: Empty data for encryption`,
|
|
234
243
|
desc: "Data must be a non-empty string"
|
|
235
244
|
});
|
|
236
245
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
246
|
+
if (!chunkBHG5RSUV_cjs.$isPlainObj(options)) {
|
|
247
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
248
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Encryption")}: Invalid options`,
|
|
249
|
+
desc: "Options must be an object"
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
const outputEncoding = options.outputEncoding ?? "base64url";
|
|
253
|
+
if (!chunkBHG5RSUV_cjs.CIPHER_ENCODING.includes(outputEncoding)) {
|
|
254
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
255
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Encryption")}: Unsupported output encoding: ${outputEncoding}`,
|
|
241
256
|
desc: "Use base64, base64url, or hex"
|
|
242
257
|
});
|
|
243
258
|
}
|
|
244
|
-
const injectedKey =
|
|
259
|
+
const injectedKey = chunkBHG5RSUV_cjs.$isSecretKey(secretKey, "web");
|
|
245
260
|
if (!injectedKey) {
|
|
246
|
-
return
|
|
247
|
-
msg: `${
|
|
261
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
262
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Encryption")}: Invalid Secret Key`,
|
|
248
263
|
desc: "Expected a Web SecretKey"
|
|
249
264
|
});
|
|
250
265
|
}
|
|
251
266
|
const { result, error } = $convertStrToBytes(data, "utf8");
|
|
252
|
-
if (error) return
|
|
267
|
+
if (error) return chunkBHG5RSUV_cjs.$err(error);
|
|
253
268
|
try {
|
|
254
269
|
const iv = crypto.getRandomValues(new Uint8Array(injectedKey.injected.ivLength));
|
|
255
270
|
const cipherWithTag = await crypto.subtle.encrypt(
|
|
@@ -257,53 +272,59 @@ async function $encrypt(data, secretKey, options = {}) {
|
|
|
257
272
|
injectedKey.key,
|
|
258
273
|
result
|
|
259
274
|
);
|
|
260
|
-
const ivStr = $convertBytesToStr(iv,
|
|
261
|
-
const cipherStr = $convertBytesToStr(cipherWithTag,
|
|
275
|
+
const ivStr = $convertBytesToStr(iv, outputEncoding);
|
|
276
|
+
const cipherStr = $convertBytesToStr(cipherWithTag, outputEncoding);
|
|
262
277
|
if (ivStr.error || cipherStr.error) {
|
|
263
|
-
return
|
|
264
|
-
msg: `${
|
|
265
|
-
desc: `Conversion error: ${
|
|
278
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
279
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Encryption")}: Failed to convert IV or encrypted data`,
|
|
280
|
+
desc: `Conversion error: ${chunkBHG5RSUV_cjs.$fmtResultErr(ivStr.error || cipherStr.error)}`
|
|
266
281
|
});
|
|
267
282
|
}
|
|
268
|
-
return
|
|
283
|
+
return chunkBHG5RSUV_cjs.$ok(`${ivStr.result}.${cipherStr.result}.`);
|
|
269
284
|
} catch (error2) {
|
|
270
|
-
return
|
|
285
|
+
return chunkBHG5RSUV_cjs.$err({ msg: `${chunkBHG5RSUV_cjs.title("web", "Encryption")}: Failed to encrypt data`, desc: chunkBHG5RSUV_cjs.$fmtError(error2) });
|
|
271
286
|
}
|
|
272
287
|
}
|
|
273
|
-
async function $decrypt(encrypted, secretKey, options
|
|
274
|
-
if (
|
|
275
|
-
return
|
|
276
|
-
msg: `${
|
|
288
|
+
async function $decrypt(encrypted, secretKey, options) {
|
|
289
|
+
if (!chunkBHG5RSUV_cjs.matchEncryptedPattern(encrypted, "web")) {
|
|
290
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
291
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Decryption")}: Invalid encrypted data format`,
|
|
277
292
|
desc: 'Encrypted data must be in the format "iv.cipherWithTag."'
|
|
278
293
|
});
|
|
279
294
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
295
|
+
if (!chunkBHG5RSUV_cjs.$isPlainObj(options)) {
|
|
296
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
297
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Decryption")}: Invalid options`,
|
|
298
|
+
desc: "Options must be an object"
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
const inputEncoding = options.inputEncoding ?? "base64url";
|
|
302
|
+
if (!chunkBHG5RSUV_cjs.CIPHER_ENCODING.includes(inputEncoding)) {
|
|
303
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
304
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Decryption")}: Unsupported input encoding: ${inputEncoding}`,
|
|
284
305
|
desc: "Use base64, base64url, or hex"
|
|
285
306
|
});
|
|
286
307
|
}
|
|
287
308
|
const [iv, encryptedWithTag] = encrypted.split(".", 3);
|
|
288
|
-
if (!
|
|
289
|
-
return
|
|
290
|
-
msg: `${
|
|
309
|
+
if (!chunkBHG5RSUV_cjs.$isStr(iv) || !chunkBHG5RSUV_cjs.$isStr(encryptedWithTag)) {
|
|
310
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
311
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Decryption")}: Invalid encrypted data`,
|
|
291
312
|
desc: "Encrypted data must contain valid IV, encrypted and tag components"
|
|
292
313
|
});
|
|
293
314
|
}
|
|
294
|
-
const injectedKey =
|
|
315
|
+
const injectedKey = chunkBHG5RSUV_cjs.$isSecretKey(secretKey, "web");
|
|
295
316
|
if (!injectedKey) {
|
|
296
|
-
return
|
|
297
|
-
msg: `${
|
|
317
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
318
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Decryption")}: Invalid Secret Key`,
|
|
298
319
|
desc: "Expected a Web SecretKey"
|
|
299
320
|
});
|
|
300
321
|
}
|
|
301
|
-
const ivBytes = $convertStrToBytes(iv,
|
|
302
|
-
const cipherWithTagBytes = $convertStrToBytes(encryptedWithTag,
|
|
322
|
+
const ivBytes = $convertStrToBytes(iv, inputEncoding);
|
|
323
|
+
const cipherWithTagBytes = $convertStrToBytes(encryptedWithTag, inputEncoding);
|
|
303
324
|
if (ivBytes.error || cipherWithTagBytes.error) {
|
|
304
|
-
return
|
|
305
|
-
msg: `${
|
|
306
|
-
desc: `Conversion error: ${
|
|
325
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
326
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Decryption")}: Failed to convert IV or encrypted data`,
|
|
327
|
+
desc: `Conversion error: ${chunkBHG5RSUV_cjs.$fmtResultErr(ivBytes.error || cipherWithTagBytes.error)}`
|
|
307
328
|
});
|
|
308
329
|
}
|
|
309
330
|
try {
|
|
@@ -314,87 +335,99 @@ async function $decrypt(encrypted, secretKey, options = {}) {
|
|
|
314
335
|
);
|
|
315
336
|
return $convertBytesToStr(decrypted, "utf8");
|
|
316
337
|
} catch (error) {
|
|
317
|
-
return
|
|
338
|
+
return chunkBHG5RSUV_cjs.$err({ msg: `${chunkBHG5RSUV_cjs.title("web", "Decryption")}: Failed to decrypt data`, desc: chunkBHG5RSUV_cjs.$fmtError(error) });
|
|
318
339
|
}
|
|
319
340
|
}
|
|
320
|
-
async function $encryptObj(data, secretKey, options
|
|
321
|
-
const { result, error } =
|
|
322
|
-
if (error) return
|
|
341
|
+
async function $encryptObj(data, secretKey, options) {
|
|
342
|
+
const { result, error } = chunkBHG5RSUV_cjs.$stringifyObj(data);
|
|
343
|
+
if (error) return chunkBHG5RSUV_cjs.$err(error);
|
|
323
344
|
return await $encrypt(result, secretKey, options);
|
|
324
345
|
}
|
|
325
|
-
async function $decryptObj(encrypted, secretKey, options
|
|
346
|
+
async function $decryptObj(encrypted, secretKey, options) {
|
|
326
347
|
const { result, error } = await $decrypt(encrypted, secretKey, options);
|
|
327
|
-
if (error) return
|
|
328
|
-
return
|
|
348
|
+
if (error) return chunkBHG5RSUV_cjs.$err(error);
|
|
349
|
+
return chunkBHG5RSUV_cjs.$parseToObj(result);
|
|
329
350
|
}
|
|
330
|
-
async function $hash(data, options
|
|
331
|
-
if (!
|
|
332
|
-
return
|
|
351
|
+
async function $hash(data, options) {
|
|
352
|
+
if (!chunkBHG5RSUV_cjs.$isStr(data)) {
|
|
353
|
+
return chunkBHG5RSUV_cjs.$err({ msg: `${chunkBHG5RSUV_cjs.title("web", "Hashing")}: Empty data for hashing`, desc: "Data must be a non-empty string" });
|
|
333
354
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
355
|
+
if (!chunkBHG5RSUV_cjs.$isPlainObj(options)) {
|
|
356
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
357
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Hashing")}: Invalid options`,
|
|
358
|
+
desc: "Options must be an object"
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
const outputEncoding = options.outputEncoding ?? "base64url";
|
|
362
|
+
if (!chunkBHG5RSUV_cjs.CIPHER_ENCODING.includes(outputEncoding)) {
|
|
363
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
364
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Hashing")}: Unsupported output encoding: ${outputEncoding}`,
|
|
338
365
|
desc: "Use base64, base64url, or hex"
|
|
339
366
|
});
|
|
340
367
|
}
|
|
341
368
|
const digest = options.digest ?? "sha256";
|
|
342
|
-
if (!(digest in
|
|
343
|
-
return
|
|
344
|
-
msg: `${
|
|
345
|
-
desc: `Supported digests are: ${Object.keys(
|
|
369
|
+
if (!(digest in chunkBHG5RSUV_cjs.DIGEST_ALGORITHMS)) {
|
|
370
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
371
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Hashing")}: Unsupported digest: ${digest}`,
|
|
372
|
+
desc: `Supported digests are: ${Object.keys(chunkBHG5RSUV_cjs.DIGEST_ALGORITHMS).join(", ")}`
|
|
346
373
|
});
|
|
347
374
|
}
|
|
348
|
-
const digestAlgo =
|
|
375
|
+
const digestAlgo = chunkBHG5RSUV_cjs.DIGEST_ALGORITHMS[digest];
|
|
349
376
|
const { result, error } = $convertStrToBytes(data, "utf8");
|
|
350
|
-
if (error) return
|
|
377
|
+
if (error) return chunkBHG5RSUV_cjs.$err(error);
|
|
351
378
|
try {
|
|
352
379
|
const hashed = await crypto.subtle.digest(digestAlgo.web, result);
|
|
353
|
-
return $convertBytesToStr(hashed,
|
|
380
|
+
return $convertBytesToStr(hashed, outputEncoding);
|
|
354
381
|
} catch (error2) {
|
|
355
|
-
return
|
|
382
|
+
return chunkBHG5RSUV_cjs.$err({ msg: `${chunkBHG5RSUV_cjs.title("web", "Hashing")}: Failed to hash data`, desc: chunkBHG5RSUV_cjs.$fmtError(error2) });
|
|
356
383
|
}
|
|
357
384
|
}
|
|
358
|
-
async function $hashPassword(password, options
|
|
359
|
-
if (!
|
|
360
|
-
return
|
|
361
|
-
msg: `${
|
|
385
|
+
async function $hashPassword(password, options) {
|
|
386
|
+
if (!chunkBHG5RSUV_cjs.$isStr(password)) {
|
|
387
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
388
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Password Hashing")}: Empty password`,
|
|
362
389
|
desc: "Password must be a non-empty string"
|
|
363
390
|
});
|
|
364
391
|
}
|
|
392
|
+
if (!chunkBHG5RSUV_cjs.$isPlainObj(options)) {
|
|
393
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
394
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Password Hashing")}: Invalid options`,
|
|
395
|
+
desc: "Options must be an object"
|
|
396
|
+
});
|
|
397
|
+
}
|
|
365
398
|
const digest = options.digest ?? "sha512";
|
|
366
|
-
if (!(digest in
|
|
367
|
-
return
|
|
368
|
-
msg: `${
|
|
369
|
-
desc: `Supported digests are: ${Object.keys(
|
|
399
|
+
if (!(digest in chunkBHG5RSUV_cjs.DIGEST_ALGORITHMS)) {
|
|
400
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
401
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Password Hashing")}: Unsupported digest: ${digest}`,
|
|
402
|
+
desc: `Supported digests are: ${Object.keys(chunkBHG5RSUV_cjs.DIGEST_ALGORITHMS).join(", ")}`
|
|
370
403
|
});
|
|
371
404
|
}
|
|
372
|
-
const digestAlgo =
|
|
373
|
-
const
|
|
374
|
-
if (!
|
|
375
|
-
return
|
|
376
|
-
msg: `${
|
|
405
|
+
const digestAlgo = chunkBHG5RSUV_cjs.DIGEST_ALGORITHMS[digest];
|
|
406
|
+
const outputEncoding = options.outputEncoding ?? "base64url";
|
|
407
|
+
if (!chunkBHG5RSUV_cjs.CIPHER_ENCODING.includes(outputEncoding)) {
|
|
408
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
409
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Password Hashing")}: Unsupported output encoding: ${outputEncoding}`,
|
|
377
410
|
desc: "Use base64, base64url, or hex"
|
|
378
411
|
});
|
|
379
412
|
}
|
|
380
413
|
const saltLength = options.saltLength ?? 16;
|
|
381
414
|
if (typeof saltLength !== "number" || saltLength < 8) {
|
|
382
|
-
return
|
|
383
|
-
msg: `${
|
|
415
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
416
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Password Hashing")}: Weak salt length`,
|
|
384
417
|
desc: "Salt length must be a number and at least 8 bytes (recommended 16)"
|
|
385
418
|
});
|
|
386
419
|
}
|
|
387
420
|
const iterations = options.iterations ?? 32e4;
|
|
388
421
|
if (typeof iterations !== "number" || iterations < 1e3) {
|
|
389
|
-
return
|
|
390
|
-
msg: `${
|
|
422
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
423
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Password Hashing")}: Weak iteration count`,
|
|
391
424
|
desc: "Iterations must be a number and at least 1000 (recommended 320,000 or more)"
|
|
392
425
|
});
|
|
393
426
|
}
|
|
394
427
|
const keyLength = options.keyLength ?? 64;
|
|
395
428
|
if (typeof keyLength !== "number" || keyLength < 16) {
|
|
396
|
-
return
|
|
397
|
-
msg: `${
|
|
429
|
+
return chunkBHG5RSUV_cjs.$err({
|
|
430
|
+
msg: `${chunkBHG5RSUV_cjs.title("web", "Password Hashing")}: Weak key length`,
|
|
398
431
|
desc: "Key length must be a number and at least 16 bytes (recommended 64)"
|
|
399
432
|
});
|
|
400
433
|
}
|
|
@@ -412,29 +445,31 @@ async function $hashPassword(password, options = {}) {
|
|
|
412
445
|
baseKey,
|
|
413
446
|
keyLength * 8
|
|
414
447
|
);
|
|
415
|
-
const saltStr = $convertBytesToStr(salt,
|
|
416
|
-
if (saltStr.error) return
|
|
417
|
-
const hashedPasswordStr = $convertBytesToStr(bits,
|
|
418
|
-
if (hashedPasswordStr.error) return
|
|
419
|
-
return
|
|
448
|
+
const saltStr = $convertBytesToStr(salt, outputEncoding);
|
|
449
|
+
if (saltStr.error) return chunkBHG5RSUV_cjs.$err(saltStr.error);
|
|
450
|
+
const hashedPasswordStr = $convertBytesToStr(bits, outputEncoding);
|
|
451
|
+
if (hashedPasswordStr.error) return chunkBHG5RSUV_cjs.$err(hashedPasswordStr.error);
|
|
452
|
+
return chunkBHG5RSUV_cjs.$ok({ result: hashedPasswordStr.result, salt: saltStr.result });
|
|
420
453
|
} catch (error) {
|
|
421
|
-
return
|
|
454
|
+
return chunkBHG5RSUV_cjs.$err({ msg: `${chunkBHG5RSUV_cjs.title("web", "Password Hashing")}: Failed to hash password`, desc: chunkBHG5RSUV_cjs.$fmtError(error) });
|
|
422
455
|
}
|
|
423
456
|
}
|
|
424
|
-
async function $verifyPassword(password, hashedPassword, salt, options
|
|
425
|
-
if (!
|
|
457
|
+
async function $verifyPassword(password, hashedPassword, salt, options) {
|
|
458
|
+
if (!chunkBHG5RSUV_cjs.$isStr(password) || !chunkBHG5RSUV_cjs.$isStr(hashedPassword) || !chunkBHG5RSUV_cjs.$isStr(salt) || !chunkBHG5RSUV_cjs.$isPlainObj(options)) {
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
426
461
|
const digest = options.digest ?? "sha512";
|
|
427
|
-
if (!(digest in
|
|
428
|
-
const digestAlgo =
|
|
429
|
-
const
|
|
430
|
-
if (!
|
|
462
|
+
if (!(digest in chunkBHG5RSUV_cjs.DIGEST_ALGORITHMS)) return false;
|
|
463
|
+
const digestAlgo = chunkBHG5RSUV_cjs.DIGEST_ALGORITHMS[digest];
|
|
464
|
+
const inputEncoding = options.inputEncoding ?? "base64url";
|
|
465
|
+
if (!chunkBHG5RSUV_cjs.CIPHER_ENCODING.includes(inputEncoding)) return false;
|
|
431
466
|
const iterations = options.iterations ?? 32e4;
|
|
432
467
|
if (typeof iterations !== "number" || iterations < 1e3) return false;
|
|
433
468
|
const keyLength = options.keyLength ?? 64;
|
|
434
469
|
if (typeof keyLength !== "number" || keyLength < 16) return false;
|
|
435
|
-
const saltBytes = $convertStrToBytes(salt,
|
|
470
|
+
const saltBytes = $convertStrToBytes(salt, inputEncoding);
|
|
436
471
|
if (saltBytes.error) return false;
|
|
437
|
-
const hashedPasswordBytes = $convertStrToBytes(hashedPassword,
|
|
472
|
+
const hashedPasswordBytes = $convertStrToBytes(hashedPassword, inputEncoding);
|
|
438
473
|
if (hashedPasswordBytes.error) return false;
|
|
439
474
|
try {
|
|
440
475
|
const baseKey = await crypto.subtle.importKey(
|
|
@@ -470,14 +505,14 @@ async function $verifyPassword(password, hashedPassword, salt, options = {}) {
|
|
|
470
505
|
|
|
471
506
|
// src/web/kit.ts
|
|
472
507
|
function isWebSecretKey(x) {
|
|
473
|
-
return
|
|
508
|
+
return chunkBHG5RSUV_cjs.$isSecretKey(x, "web") !== null;
|
|
474
509
|
}
|
|
475
510
|
function tryGenerateUuid() {
|
|
476
511
|
return $generateUuid();
|
|
477
512
|
}
|
|
478
513
|
function generateUuid() {
|
|
479
514
|
const { result, error } = $generateUuid();
|
|
480
|
-
if (error) throw new Error(
|
|
515
|
+
if (error) throw new Error(chunkBHG5RSUV_cjs.$fmtResultErr(error));
|
|
481
516
|
return result;
|
|
482
517
|
}
|
|
483
518
|
async function tryCreateSecretKey(secret, options = {}) {
|
|
@@ -485,7 +520,7 @@ async function tryCreateSecretKey(secret, options = {}) {
|
|
|
485
520
|
}
|
|
486
521
|
async function createSecretKey(secret, options = {}) {
|
|
487
522
|
const { result, error } = await $createSecretKey(secret, options);
|
|
488
|
-
if (error) throw new Error(
|
|
523
|
+
if (error) throw new Error(chunkBHG5RSUV_cjs.$fmtResultErr(error));
|
|
489
524
|
return result;
|
|
490
525
|
}
|
|
491
526
|
async function tryEncrypt(data, secretKey, options = {}) {
|
|
@@ -493,7 +528,7 @@ async function tryEncrypt(data, secretKey, options = {}) {
|
|
|
493
528
|
}
|
|
494
529
|
async function encrypt(data, secretKey, options = {}) {
|
|
495
530
|
const { result, error } = await $encrypt(data, secretKey, options);
|
|
496
|
-
if (error) throw new Error(
|
|
531
|
+
if (error) throw new Error(chunkBHG5RSUV_cjs.$fmtResultErr(error));
|
|
497
532
|
return result;
|
|
498
533
|
}
|
|
499
534
|
async function tryDecrypt(encrypted, secretKey, options = {}) {
|
|
@@ -501,7 +536,7 @@ async function tryDecrypt(encrypted, secretKey, options = {}) {
|
|
|
501
536
|
}
|
|
502
537
|
async function decrypt(encrypted, secretKey, options = {}) {
|
|
503
538
|
const { result, error } = await $decrypt(encrypted, secretKey, options);
|
|
504
|
-
if (error) throw new Error(
|
|
539
|
+
if (error) throw new Error(chunkBHG5RSUV_cjs.$fmtResultErr(error));
|
|
505
540
|
return result;
|
|
506
541
|
}
|
|
507
542
|
async function tryEncryptObj(data, secretKey, options = {}) {
|
|
@@ -509,7 +544,7 @@ async function tryEncryptObj(data, secretKey, options = {}) {
|
|
|
509
544
|
}
|
|
510
545
|
async function encryptObj(data, secretKey, options = {}) {
|
|
511
546
|
const { result, error } = await $encryptObj(data, secretKey, options);
|
|
512
|
-
if (error) throw new Error(
|
|
547
|
+
if (error) throw new Error(chunkBHG5RSUV_cjs.$fmtResultErr(error));
|
|
513
548
|
return result;
|
|
514
549
|
}
|
|
515
550
|
async function tryDecryptObj(encrypted, secretKey, options = {}) {
|
|
@@ -517,7 +552,7 @@ async function tryDecryptObj(encrypted, secretKey, options = {}) {
|
|
|
517
552
|
}
|
|
518
553
|
async function decryptObj(encrypted, secretKey, options = {}) {
|
|
519
554
|
const { result, error } = await $decryptObj(encrypted, secretKey, options);
|
|
520
|
-
if (error) throw new Error(
|
|
555
|
+
if (error) throw new Error(chunkBHG5RSUV_cjs.$fmtResultErr(error));
|
|
521
556
|
return result;
|
|
522
557
|
}
|
|
523
558
|
async function tryHash(data, options = {}) {
|
|
@@ -525,16 +560,16 @@ async function tryHash(data, options = {}) {
|
|
|
525
560
|
}
|
|
526
561
|
async function hash(data, options = {}) {
|
|
527
562
|
const { result, error } = await $hash(data, options);
|
|
528
|
-
if (error) throw new Error(
|
|
563
|
+
if (error) throw new Error(chunkBHG5RSUV_cjs.$fmtResultErr(error));
|
|
529
564
|
return result;
|
|
530
565
|
}
|
|
531
566
|
async function tryHashPassword(password, options = {}) {
|
|
532
567
|
return await $hashPassword(password, options);
|
|
533
568
|
}
|
|
534
569
|
async function hashPassword(password, options = {}) {
|
|
535
|
-
const {
|
|
536
|
-
if (error) throw new Error(
|
|
537
|
-
return {
|
|
570
|
+
const { result, salt, error } = await $hashPassword(password, options);
|
|
571
|
+
if (error) throw new Error(chunkBHG5RSUV_cjs.$fmtResultErr(error));
|
|
572
|
+
return { result, salt };
|
|
538
573
|
}
|
|
539
574
|
async function verifyPassword(password, hashedPassword, salt, options = {}) {
|
|
540
575
|
return await $verifyPassword(password, hashedPassword, salt, options);
|
|
@@ -544,7 +579,7 @@ function tryConvertStrToBytes(data, inputEncoding = "utf8") {
|
|
|
544
579
|
}
|
|
545
580
|
function convertStrToBytes(data, inputEncoding = "utf8") {
|
|
546
581
|
const { result, error } = $convertStrToBytes(data, inputEncoding);
|
|
547
|
-
if (error) throw new Error(
|
|
582
|
+
if (error) throw new Error(chunkBHG5RSUV_cjs.$fmtResultErr(error));
|
|
548
583
|
return result;
|
|
549
584
|
}
|
|
550
585
|
function tryConvertBytesToStr(data, outputEncoding = "utf8") {
|
|
@@ -552,7 +587,7 @@ function tryConvertBytesToStr(data, outputEncoding = "utf8") {
|
|
|
552
587
|
}
|
|
553
588
|
function convertBytesToStr(data, outputEncoding = "utf8") {
|
|
554
589
|
const { result, error } = $convertBytesToStr(data, outputEncoding);
|
|
555
|
-
if (error) throw new Error(
|
|
590
|
+
if (error) throw new Error(chunkBHG5RSUV_cjs.$fmtResultErr(error));
|
|
556
591
|
return result;
|
|
557
592
|
}
|
|
558
593
|
function tryConvertEncoding(data, from, to) {
|
|
@@ -560,7 +595,7 @@ function tryConvertEncoding(data, from, to) {
|
|
|
560
595
|
}
|
|
561
596
|
function convertEncoding(data, from, to) {
|
|
562
597
|
const { result, error } = $convertEncoding(data, from, to);
|
|
563
|
-
if (error) throw new Error(
|
|
598
|
+
if (error) throw new Error(chunkBHG5RSUV_cjs.$fmtResultErr(error));
|
|
564
599
|
return result;
|
|
565
600
|
}
|
|
566
601
|
|
|
@@ -589,5 +624,5 @@ exports.tryGenerateUuid = tryGenerateUuid;
|
|
|
589
624
|
exports.tryHash = tryHash;
|
|
590
625
|
exports.tryHashPassword = tryHashPassword;
|
|
591
626
|
exports.verifyPassword = verifyPassword;
|
|
592
|
-
//# sourceMappingURL=chunk-
|
|
593
|
-
//# sourceMappingURL=chunk-
|
|
627
|
+
//# sourceMappingURL=chunk-UVEMRK5F.cjs.map
|
|
628
|
+
//# sourceMappingURL=chunk-UVEMRK5F.cjs.map
|