cipher-kit 2.0.0-beta.2 → 2.0.0-beta.4
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/{chunk-SUGN4VDZ.js → chunk-LHB5NXYW.js} +85 -77
- package/dist/chunk-LHB5NXYW.js.map +1 -0
- package/dist/{chunk-AEQNI5EZ.js → chunk-N5T4PNG7.js} +75 -72
- package/dist/chunk-N5T4PNG7.js.map +1 -0
- package/dist/{chunk-3XGARINH.cjs → chunk-OL2AIXWK.cjs} +156 -152
- package/dist/chunk-OL2AIXWK.cjs.map +1 -0
- package/dist/{chunk-RXXVBCWL.cjs → chunk-UIV6DG54.cjs} +37 -38
- package/dist/chunk-UIV6DG54.cjs.map +1 -0
- package/dist/{chunk-WIZT7AYM.cjs → chunk-XIWV7XVI.cjs} +171 -162
- package/dist/chunk-XIWV7XVI.cjs.map +1 -0
- package/dist/{chunk-LOJKJJX5.js → chunk-YMNOTRET.js} +34 -37
- package/dist/chunk-YMNOTRET.js.map +1 -0
- package/dist/export-D1Vh79Qw.d.ts +417 -0
- package/dist/export-DGrELdz_.d.ts +416 -0
- package/dist/export-DXRl-ncG.d.cts +417 -0
- package/dist/export-Gd8hafl6.d.cts +416 -0
- package/dist/index.cjs +14 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -4
- package/dist/index.d.ts +52 -4
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/node.cjs +35 -35
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +2 -2
- package/dist/validate-Cb7IOrPo.d.cts +373 -0
- package/dist/validate-Cb7IOrPo.d.ts +373 -0
- package/dist/web-api.cjs +35 -35
- 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 +1 -1
- package/dist/chunk-3XGARINH.cjs.map +0 -1
- package/dist/chunk-AEQNI5EZ.js.map +0 -1
- package/dist/chunk-LOJKJJX5.js.map +0 -1
- package/dist/chunk-RXXVBCWL.cjs.map +0 -1
- package/dist/chunk-SUGN4VDZ.js.map +0 -1
- package/dist/chunk-WIZT7AYM.cjs.map +0 -1
- package/dist/export-Bq9tslUU.d.ts +0 -252
- package/dist/export-C0WDJZUy.d.ts +0 -251
- package/dist/export-LPOfeH2z.d.cts +0 -251
- package/dist/export-RD2Af4CJ.d.cts +0 -252
- package/dist/validate-CS4PFmY1.d.cts +0 -159
- package/dist/validate-CS4PFmY1.d.ts +0 -159
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __export, $fmtResultErr, $ok, $err, $fmtError, $isStr, ENCRYPTION_ALGORITHMS, DIGEST_ALGORITHMS,
|
|
1
|
+
import { __export, $isSecretKey, $fmtResultErr, $ok, $err, $fmtError, title, $isStr, ENCRYPTION_ALGORITHMS, DIGEST_ALGORITHMS, CIPHER_ENCODING, matchPattern, $stringifyObj, $parseToObj, ENCODING } from './chunk-YMNOTRET.js';
|
|
2
2
|
import { Buffer } from 'buffer';
|
|
3
3
|
import nodeCrypto from 'crypto';
|
|
4
4
|
|
|
@@ -16,6 +16,7 @@ __export(kit_exports, {
|
|
|
16
16
|
generateUuid: () => generateUuid,
|
|
17
17
|
hash: () => hash,
|
|
18
18
|
hashPassword: () => hashPassword,
|
|
19
|
+
isNodeSecretKey: () => isNodeSecretKey,
|
|
19
20
|
tryConvertBytesToStr: () => tryConvertBytesToStr,
|
|
20
21
|
tryConvertEncoding: () => tryConvertEncoding,
|
|
21
22
|
tryConvertStrToBytes: () => tryConvertStrToBytes,
|
|
@@ -36,7 +37,7 @@ function $convertStrToBytes(data, inputEncoding = "utf8") {
|
|
|
36
37
|
desc: "Data must be a non-empty string"
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
|
-
if (!
|
|
40
|
+
if (!ENCODING.includes(inputEncoding)) {
|
|
40
41
|
return $err({
|
|
41
42
|
msg: `Crypto NodeJS API - String to Bytes: Unsupported encoding: ${inputEncoding}`,
|
|
42
43
|
desc: "Use base64, base64url, hex, utf8, or latin1"
|
|
@@ -55,7 +56,7 @@ function $convertBytesToStr(data, outputEncoding = "utf8") {
|
|
|
55
56
|
desc: "Data must be a Buffer"
|
|
56
57
|
});
|
|
57
58
|
}
|
|
58
|
-
if (!
|
|
59
|
+
if (!ENCODING.includes(outputEncoding)) {
|
|
59
60
|
return $err({
|
|
60
61
|
msg: `Crypto NodeJS API - Bytes to String: Unsupported encoding: ${outputEncoding}`,
|
|
61
62
|
desc: "Use base64, base64url, hex, utf8, or latin1"
|
|
@@ -74,7 +75,7 @@ function $convertEncoding(data, from, to) {
|
|
|
74
75
|
desc: "Data must be a non-empty string"
|
|
75
76
|
});
|
|
76
77
|
}
|
|
77
|
-
if (!
|
|
78
|
+
if (!ENCODING.includes(from) || !ENCODING.includes(to)) {
|
|
78
79
|
return $err({
|
|
79
80
|
msg: `Crypto NodeJS API - Convert Format: Unsupported encoding: from ${from} to ${to}`,
|
|
80
81
|
desc: "Use base64, base64url, hex, utf8, or latin1"
|
|
@@ -90,38 +91,38 @@ function $generateUuid() {
|
|
|
90
91
|
try {
|
|
91
92
|
return $ok(nodeCrypto.randomUUID());
|
|
92
93
|
} catch (error) {
|
|
93
|
-
return $err({ msg: "
|
|
94
|
+
return $err({ msg: `${title("node", "UUID Generation")}: Failed to generate UUID`, desc: $fmtError(error) });
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
function $createSecretKey(secret, options = {}) {
|
|
97
98
|
if (!$isStr(secret)) {
|
|
98
|
-
return $err({ msg: "
|
|
99
|
+
return $err({ msg: `${title("node", "Key Generation")}: Empty Secret`, desc: "Secret must be a non-empty string" });
|
|
99
100
|
}
|
|
100
101
|
const algorithm = options.algorithm ?? "aes256gcm";
|
|
101
102
|
if (!(algorithm in ENCRYPTION_ALGORITHMS)) {
|
|
102
103
|
return $err({
|
|
103
|
-
msg:
|
|
104
|
+
msg: `${title("node", "Key Generation")}: Unsupported algorithm: ${algorithm}`,
|
|
104
105
|
desc: `Supported algorithms are: ${Object.keys(ENCRYPTION_ALGORITHMS).join(", ")}`
|
|
105
106
|
});
|
|
106
107
|
}
|
|
107
108
|
const digest = options.digest ?? "sha256";
|
|
108
109
|
if (!(digest in DIGEST_ALGORITHMS)) {
|
|
109
110
|
return $err({
|
|
110
|
-
msg:
|
|
111
|
+
msg: `${title("node", "Key Generation")}: Unsupported digest: ${digest}`,
|
|
111
112
|
desc: `Supported digests are: ${Object.keys(DIGEST_ALGORITHMS).join(", ")}`
|
|
112
113
|
});
|
|
113
114
|
}
|
|
114
115
|
const salt = options.salt ?? "cipher-kit-salt";
|
|
115
116
|
if (!$isStr(salt, 8)) {
|
|
116
117
|
return $err({
|
|
117
|
-
msg: "
|
|
118
|
+
msg: `${title("node", "Key Generation")}: Weak salt`,
|
|
118
119
|
desc: "Salt must be a non-empty string with at least 8 characters"
|
|
119
120
|
});
|
|
120
121
|
}
|
|
121
122
|
const info = options.info ?? "cipher-kit";
|
|
122
123
|
if (!$isStr(info)) {
|
|
123
124
|
return $err({
|
|
124
|
-
msg: "
|
|
125
|
+
msg: `${title("node", "Key Generation")}: Invalid info`,
|
|
125
126
|
desc: "Info must be a non-empty string"
|
|
126
127
|
});
|
|
127
128
|
}
|
|
@@ -139,100 +140,100 @@ function $createSecretKey(secret, options = {}) {
|
|
|
139
140
|
const secretKey = Object.freeze({
|
|
140
141
|
platform: "node",
|
|
141
142
|
digest,
|
|
142
|
-
|
|
143
|
+
algorithm,
|
|
143
144
|
key
|
|
144
145
|
});
|
|
145
146
|
return $ok({ result: secretKey });
|
|
146
147
|
} catch (error) {
|
|
147
|
-
return $err({ msg: "
|
|
148
|
+
return $err({ msg: `${title("node", "Key Generation")}: Failed to create secret key`, desc: $fmtError(error) });
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
151
|
function $encrypt(data, secretKey, options = {}) {
|
|
151
152
|
if (!$isStr(data)) {
|
|
152
153
|
return $err({
|
|
153
|
-
msg: "
|
|
154
|
+
msg: `${title("node", "Encryption")}: Empty data for encryption`,
|
|
154
155
|
desc: "Data must be a non-empty string"
|
|
155
156
|
});
|
|
156
157
|
}
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
if (!ENCODINGS.includes(inputEncoding) || !ENCODINGS.includes(outputEncoding)) {
|
|
158
|
+
const encoding = options.encoding ?? "base64url";
|
|
159
|
+
if (!CIPHER_ENCODING.includes(encoding)) {
|
|
160
160
|
return $err({
|
|
161
|
-
msg:
|
|
162
|
-
desc: "Use base64, base64url,
|
|
161
|
+
msg: `${title("node", "Encryption")}: Unsupported output encoding: ${encoding}`,
|
|
162
|
+
desc: "Use base64, base64url, or hex"
|
|
163
163
|
});
|
|
164
164
|
}
|
|
165
|
-
|
|
165
|
+
const injectedKey = $isSecretKey(secretKey, "node");
|
|
166
|
+
if (!injectedKey) {
|
|
166
167
|
return $err({
|
|
167
|
-
msg: "
|
|
168
|
+
msg: `${title("node", "Encryption")}: Invalid Secret Key`,
|
|
168
169
|
desc: "Expected a Node SecretKey"
|
|
169
170
|
});
|
|
170
171
|
}
|
|
171
|
-
const { result, error } = $convertStrToBytes(data,
|
|
172
|
+
const { result, error } = $convertStrToBytes(data, "utf8");
|
|
172
173
|
if (error) return $err(error);
|
|
173
174
|
try {
|
|
174
|
-
const iv = nodeCrypto.randomBytes(
|
|
175
|
-
const cipher = nodeCrypto.createCipheriv(
|
|
175
|
+
const iv = nodeCrypto.randomBytes(injectedKey.injected.ivLength);
|
|
176
|
+
const cipher = nodeCrypto.createCipheriv(injectedKey.injected.node, injectedKey.key, iv);
|
|
176
177
|
const encrypted = Buffer.concat([cipher.update(result), cipher.final()]);
|
|
177
178
|
const tag = cipher.getAuthTag();
|
|
178
|
-
const ivStr = $convertBytesToStr(iv,
|
|
179
|
-
const cipherStr = $convertBytesToStr(encrypted,
|
|
180
|
-
const tagStr = $convertBytesToStr(tag,
|
|
179
|
+
const ivStr = $convertBytesToStr(iv, encoding);
|
|
180
|
+
const cipherStr = $convertBytesToStr(encrypted, encoding);
|
|
181
|
+
const tagStr = $convertBytesToStr(tag, encoding);
|
|
181
182
|
if (ivStr.error || cipherStr.error || tagStr.error) {
|
|
182
183
|
return $err({
|
|
183
184
|
msg: "Crypto NodeJS API - Encryption: Failed to convert IV or encrypted data or tag",
|
|
184
|
-
desc: `Conversion error: ${ivStr.error || cipherStr.error || tagStr.error}`
|
|
185
|
+
desc: `Conversion error: ${$fmtResultErr(ivStr.error || cipherStr.error || tagStr.error)}`
|
|
185
186
|
});
|
|
186
187
|
}
|
|
187
188
|
return $ok(`${ivStr.result}.${cipherStr.result}.${tagStr.result}.`);
|
|
188
189
|
} catch (error2) {
|
|
189
|
-
return $err({ msg: "
|
|
190
|
+
return $err({ msg: `${title("node", "Encryption")}: Failed to encrypt data`, desc: $fmtError(error2) });
|
|
190
191
|
}
|
|
191
192
|
}
|
|
192
193
|
function $decrypt(encrypted, secretKey, options = {}) {
|
|
193
194
|
if (matchPattern(encrypted, "node") === false) {
|
|
194
195
|
return $err({
|
|
195
|
-
msg: "
|
|
196
|
+
msg: `${title("node", "Decryption")}: Invalid encrypted data format`,
|
|
196
197
|
desc: 'Encrypted data must be in the format "iv.cipher.tag."'
|
|
197
198
|
});
|
|
198
199
|
}
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
if (!ENCODINGS.includes(inputEncoding) || !ENCODINGS.includes(outputEncoding)) {
|
|
200
|
+
const encoding = options.encoding ?? "base64url";
|
|
201
|
+
if (!CIPHER_ENCODING.includes(encoding)) {
|
|
202
202
|
return $err({
|
|
203
|
-
msg:
|
|
204
|
-
desc: "Use base64, base64url,
|
|
203
|
+
msg: `${title("node", "Decryption")}: Unsupported input encoding: ${encoding}`,
|
|
204
|
+
desc: "Use base64, base64url, or hex"
|
|
205
205
|
});
|
|
206
206
|
}
|
|
207
207
|
const [iv, cipher, tag] = encrypted.split(".", 4);
|
|
208
208
|
if (!$isStr(iv) || !$isStr(cipher) || !$isStr(tag)) {
|
|
209
209
|
return $err({
|
|
210
|
-
msg: "
|
|
210
|
+
msg: `${title("node", "Decryption")}: Invalid encrypted data`,
|
|
211
211
|
desc: "Encrypted data must contain valid IV, encrypted data, and tag components"
|
|
212
212
|
});
|
|
213
213
|
}
|
|
214
|
-
|
|
214
|
+
const injectedKey = $isSecretKey(secretKey, "node");
|
|
215
|
+
if (!injectedKey) {
|
|
215
216
|
return $err({
|
|
216
217
|
msg: "Crypto NodeJS API - Decryption: Invalid Secret Key",
|
|
217
218
|
desc: "Expected a Node SecretKey"
|
|
218
219
|
});
|
|
219
220
|
}
|
|
220
|
-
const ivBytes = $convertStrToBytes(iv,
|
|
221
|
-
const cipherBytes = $convertStrToBytes(cipher,
|
|
222
|
-
const tagBytes = $convertStrToBytes(tag,
|
|
221
|
+
const ivBytes = $convertStrToBytes(iv, encoding);
|
|
222
|
+
const cipherBytes = $convertStrToBytes(cipher, encoding);
|
|
223
|
+
const tagBytes = $convertStrToBytes(tag, encoding);
|
|
223
224
|
if (ivBytes.error || cipherBytes.error || tagBytes.error) {
|
|
224
225
|
return $err({
|
|
225
|
-
msg: "
|
|
226
|
-
desc: `Conversion error: ${ivBytes.error || cipherBytes.error || tagBytes.error}`
|
|
226
|
+
msg: `${title("node", "Decryption")}: Failed to convert IV or encrypted data or tag`,
|
|
227
|
+
desc: `Conversion error: ${$fmtResultErr(ivBytes.error || cipherBytes.error || tagBytes.error)}`
|
|
227
228
|
});
|
|
228
229
|
}
|
|
229
230
|
try {
|
|
230
|
-
const decipher = nodeCrypto.createDecipheriv(
|
|
231
|
+
const decipher = nodeCrypto.createDecipheriv(injectedKey.injected.node, injectedKey.key, ivBytes.result);
|
|
231
232
|
decipher.setAuthTag(tagBytes.result);
|
|
232
233
|
const decrypted = Buffer.concat([decipher.update(cipherBytes.result), decipher.final()]);
|
|
233
|
-
return $convertBytesToStr(decrypted,
|
|
234
|
+
return $convertBytesToStr(decrypted, "utf8");
|
|
234
235
|
} catch (error) {
|
|
235
|
-
return $err({ msg: "
|
|
236
|
+
return $err({ msg: `${title("node", "Decryption")}: Failed to decrypt data`, desc: $fmtError(error) });
|
|
236
237
|
}
|
|
237
238
|
}
|
|
238
239
|
function $encryptObj(data, secretKey, options = {}) {
|
|
@@ -248,84 +249,83 @@ function $decryptObj(encrypted, secretKey, options = {}) {
|
|
|
248
249
|
function $hash(data, options = {}) {
|
|
249
250
|
if (!$isStr(data)) {
|
|
250
251
|
return $err({
|
|
251
|
-
msg: "
|
|
252
|
+
msg: `${title("node", "Hashing")}: Empty data for hashing`,
|
|
252
253
|
desc: "Data must be a non-empty string"
|
|
253
254
|
});
|
|
254
255
|
}
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
if (!ENCODINGS.includes(inputEncoding) || !ENCODINGS.includes(outputEncoding)) {
|
|
256
|
+
const encoding = options.encoding ?? "base64url";
|
|
257
|
+
if (!CIPHER_ENCODING.includes(encoding)) {
|
|
258
258
|
return $err({
|
|
259
|
-
msg:
|
|
260
|
-
desc: "Use base64, base64url,
|
|
259
|
+
msg: `${title("node", "Hashing")}: Unsupported output encoding: ${encoding}`,
|
|
260
|
+
desc: "Use base64, base64url, or hex"
|
|
261
261
|
});
|
|
262
262
|
}
|
|
263
263
|
const digest = options.digest ?? "sha256";
|
|
264
264
|
if (!(digest in DIGEST_ALGORITHMS)) {
|
|
265
265
|
return $err({
|
|
266
|
-
msg:
|
|
266
|
+
msg: `${title("node", "Hashing")}: Unsupported digest: ${digest}`,
|
|
267
267
|
desc: `Supported digests are: ${Object.keys(DIGEST_ALGORITHMS).join(", ")}`
|
|
268
268
|
});
|
|
269
269
|
}
|
|
270
270
|
const digestAlgo = DIGEST_ALGORITHMS[digest];
|
|
271
|
-
const { result, error } = $convertStrToBytes(data,
|
|
271
|
+
const { result, error } = $convertStrToBytes(data, "utf8");
|
|
272
272
|
if (error) return $err(error);
|
|
273
273
|
try {
|
|
274
274
|
const hashed = nodeCrypto.createHash(digestAlgo.node).update(result).digest();
|
|
275
|
-
return $convertBytesToStr(hashed,
|
|
275
|
+
return $convertBytesToStr(hashed, encoding);
|
|
276
276
|
} catch (error2) {
|
|
277
|
-
return $err({ msg: "
|
|
277
|
+
return $err({ msg: `${title("node", "Hashing")}: Failed to hash data with Crypto NodeJS`, desc: $fmtError(error2) });
|
|
278
278
|
}
|
|
279
279
|
}
|
|
280
280
|
function $hashPassword(password, options = {}) {
|
|
281
281
|
if (!$isStr(password)) {
|
|
282
282
|
return $err({
|
|
283
|
-
msg: "
|
|
283
|
+
msg: `${title("node", "Password Hashing")}: Empty password for hashing`,
|
|
284
284
|
desc: "Password must be a non-empty string"
|
|
285
285
|
});
|
|
286
286
|
}
|
|
287
287
|
const digest = options.digest ?? "sha512";
|
|
288
288
|
if (!(digest in DIGEST_ALGORITHMS)) {
|
|
289
289
|
return $err({
|
|
290
|
-
msg:
|
|
290
|
+
msg: `${title("node", "Password Hashing")}: Unsupported digest: ${digest}`,
|
|
291
291
|
desc: `Supported digests are: ${Object.keys(DIGEST_ALGORITHMS).join(", ")}`
|
|
292
292
|
});
|
|
293
293
|
}
|
|
294
294
|
const digestAlgo = DIGEST_ALGORITHMS[digest];
|
|
295
|
-
const
|
|
296
|
-
if (!
|
|
295
|
+
const encoding = options.encoding ?? "base64url";
|
|
296
|
+
if (!CIPHER_ENCODING.includes(encoding)) {
|
|
297
297
|
return $err({
|
|
298
|
-
msg:
|
|
299
|
-
desc: "Use base64, base64url,
|
|
298
|
+
msg: `${title("node", "Password Hashing")}: Unsupported encoding: ${encoding}`,
|
|
299
|
+
desc: "Use base64, base64url, or hex"
|
|
300
300
|
});
|
|
301
301
|
}
|
|
302
302
|
const saltLength = options.saltLength ?? 16;
|
|
303
303
|
if (typeof saltLength !== "number" || saltLength < 8) {
|
|
304
304
|
return $err({
|
|
305
|
-
msg: "
|
|
305
|
+
msg: `${title("node", "Password Hashing")}: Weak salt length`,
|
|
306
306
|
desc: "Salt length must be a number and at least 8 bytes (recommended 16 or more)"
|
|
307
307
|
});
|
|
308
308
|
}
|
|
309
309
|
const iterations = options.iterations ?? 32e4;
|
|
310
310
|
if (typeof iterations !== "number" || iterations < 1e3) {
|
|
311
311
|
return $err({
|
|
312
|
-
msg: "
|
|
312
|
+
msg: `${title("node", "Password Hashing")}: Weak iterations count`,
|
|
313
313
|
desc: "Iterations must be a number and at least 1000 (recommended 320,000 or more)"
|
|
314
314
|
});
|
|
315
315
|
}
|
|
316
316
|
const keyLength = options.keyLength ?? 64;
|
|
317
317
|
if (typeof keyLength !== "number" || keyLength < 16) {
|
|
318
318
|
return $err({
|
|
319
|
-
msg: "
|
|
319
|
+
msg: `${title("node", "Password Hashing")}: Invalid key length`,
|
|
320
320
|
desc: "Key length must be a number and at least 16 bytes (recommended 64 or more)"
|
|
321
321
|
});
|
|
322
322
|
}
|
|
323
323
|
try {
|
|
324
324
|
const salt = nodeCrypto.randomBytes(saltLength);
|
|
325
325
|
const hash2 = nodeCrypto.pbkdf2Sync(password.normalize("NFKC"), salt, iterations, keyLength, digestAlgo.node);
|
|
326
|
-
return $ok({ salt: salt.toString(
|
|
326
|
+
return $ok({ salt: salt.toString(encoding), hash: hash2.toString(encoding) });
|
|
327
327
|
} catch (error) {
|
|
328
|
-
return $err({ msg: "
|
|
328
|
+
return $err({ msg: `${title("node", "Password Hashing")}: Failed to hash password`, desc: $fmtError(error) });
|
|
329
329
|
}
|
|
330
330
|
}
|
|
331
331
|
function $verifyPassword(password, hashedPassword, salt, options = {}) {
|
|
@@ -333,15 +333,15 @@ function $verifyPassword(password, hashedPassword, salt, options = {}) {
|
|
|
333
333
|
const digest = options.digest ?? "sha512";
|
|
334
334
|
if (!(digest in DIGEST_ALGORITHMS)) return false;
|
|
335
335
|
const digestAlgo = DIGEST_ALGORITHMS[digest];
|
|
336
|
-
const
|
|
337
|
-
if (!
|
|
336
|
+
const encoding = options.encoding ?? "base64url";
|
|
337
|
+
if (!CIPHER_ENCODING.includes(encoding)) return false;
|
|
338
338
|
const iterations = options.iterations ?? 32e4;
|
|
339
339
|
if (typeof iterations !== "number" || iterations < 1e3) return false;
|
|
340
340
|
const keyLength = options.keyLength ?? 64;
|
|
341
341
|
if (typeof keyLength !== "number" || keyLength < 16) return false;
|
|
342
|
-
const saltBytes = $convertStrToBytes(salt,
|
|
342
|
+
const saltBytes = $convertStrToBytes(salt, encoding);
|
|
343
343
|
if (saltBytes.error) return false;
|
|
344
|
-
const hashedPasswordBytes = $convertStrToBytes(hashedPassword,
|
|
344
|
+
const hashedPasswordBytes = $convertStrToBytes(hashedPassword, encoding);
|
|
345
345
|
if (hashedPasswordBytes.error) return false;
|
|
346
346
|
try {
|
|
347
347
|
return nodeCrypto.timingSafeEqual(
|
|
@@ -354,6 +354,9 @@ function $verifyPassword(password, hashedPassword, salt, options = {}) {
|
|
|
354
354
|
}
|
|
355
355
|
|
|
356
356
|
// src/node/kit.ts
|
|
357
|
+
function isNodeSecretKey(x) {
|
|
358
|
+
return $isSecretKey(x, "node") !== null;
|
|
359
|
+
}
|
|
357
360
|
function tryGenerateUuid() {
|
|
358
361
|
return $generateUuid();
|
|
359
362
|
}
|
|
@@ -446,6 +449,6 @@ function convertEncoding(data, from, to) {
|
|
|
446
449
|
return result;
|
|
447
450
|
}
|
|
448
451
|
|
|
449
|
-
export { convertBytesToStr, convertEncoding, convertStrToBytes, createSecretKey, decrypt, decryptObj, encrypt, encryptObj, generateUuid, hash, hashPassword, kit_exports, tryConvertBytesToStr, tryConvertEncoding, tryConvertStrToBytes, tryCreateSecretKey, tryDecrypt, tryDecryptObj, tryEncrypt, tryEncryptObj, tryGenerateUuid, tryHash, tryHashPassword, verifyPassword };
|
|
450
|
-
//# sourceMappingURL=chunk-
|
|
451
|
-
//# sourceMappingURL=chunk-
|
|
452
|
+
export { convertBytesToStr, convertEncoding, convertStrToBytes, createSecretKey, decrypt, decryptObj, encrypt, encryptObj, generateUuid, hash, hashPassword, isNodeSecretKey, kit_exports, tryConvertBytesToStr, tryConvertEncoding, tryConvertStrToBytes, tryCreateSecretKey, tryDecrypt, tryDecryptObj, tryEncrypt, tryEncryptObj, tryGenerateUuid, tryHash, tryHashPassword, verifyPassword };
|
|
453
|
+
//# sourceMappingURL=chunk-N5T4PNG7.js.map
|
|
454
|
+
//# sourceMappingURL=chunk-N5T4PNG7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/node/kit.ts","../src/node/node-encode.ts","../src/node/node-encrypt.ts"],"names":["Buffer","error","hash"],"mappings":"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","file":"chunk-N5T4PNG7.js","sourcesContent":["import type { Buffer } from 'node:buffer';\r\nimport { $fmtResultErr, type Result } from '~/helpers/error';\r\nimport type {\r\n CreateSecretKeyOptions,\r\n DecryptOptions,\r\n Encoding,\r\n EncryptOptions,\r\n HashOptions,\r\n HashPasswordOptions,\r\n SecretKey,\r\n VerifyPasswordOptions,\r\n} from '~/helpers/types';\r\nimport { $isSecretKey } from '~/helpers/validate';\r\nimport { $convertBytesToStr, $convertEncoding, $convertStrToBytes } from './node-encode';\r\nimport {\r\n $createSecretKey,\r\n $decrypt,\r\n $decryptObj,\r\n $encrypt,\r\n $encryptObj,\r\n $generateUuid,\r\n $hash,\r\n $hashPassword,\r\n $verifyPassword,\r\n} from './node-encrypt';\r\n\r\n/**\r\n * Type guard to check if the provided value is a SecretKey object for Node.js environment.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * Checking if the key in your hand is the right kind of key for the lock.\r\n *\r\n * @param x - The value to check.\r\n * @returns True if the value is a SecretKey object for Node.js, false otherwise.\r\n */\r\nexport function isNodeSecretKey(x: unknown): x is SecretKey<'node'> {\r\n return $isSecretKey(x, 'node') !== null;\r\n}\r\n\r\n/**\r\n * Safely generates a UUID (v4) (non-throwing).\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * It's like giving your pet a name tag with a super random name made of numbers and letters.\r\n * The chance of two pets getting the same name tag is practically zero, and it's very hard to guess!\r\n *\r\n * @returns A `Result` containing the UUID string or an error.\r\n */\r\nexport function tryGenerateUuid(): Result<string> {\r\n return $generateUuid();\r\n}\r\n\r\n/**\r\n * Generates a UUID (v4) (throwing).\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * It's like giving your pet a name tag with a super random name made of numbers and letters.\r\n * The chance of two pets getting the same name tag is practically zero, and it's very hard to guess!\r\n *\r\n * @returns A UUID string.\r\n * @throws {Error} If UUID generation fails.\r\n */\r\nexport function generateUuid(): string {\r\n const { result, error } = $generateUuid();\r\n if (error) throw new Error($fmtResultErr(error));\r\n return result;\r\n}\r\n\r\n/**\r\n * Safely derives a `SecretKey` from the provided string for encryption/decryption (non-throwing).\r\n *\r\n * Uses HKDF to derive a key from the input string.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * Imagine you want to create a special key for future use to lock your treasure box (data).\r\n * So, you stir in some secret ingredients (like salt and info) to make sure your key is one-of-a-kind.\r\n *\r\n * @param secret - The input string to derive the `SecretKey` from.\r\n * @param options.algorithm - The encryption algorithm to use (default: `'aes256gcm'`).\r\n * @param options.digest - The hash algorithm for HKDF (default: `'sha256'`).\r\n * @param options.salt - A salt string (default: `'cipher-kit-salt'`, must be ≥ 8 chars).\r\n * @param options.info - An info string (default: `'cipher-kit'`).\r\n * @returns A `Result` containing the derived `SecretKey` or an error.\r\n */\r\nexport function tryCreateSecretKey(\r\n secret: string,\r\n options: CreateSecretKeyOptions = {},\r\n): Result<{ result: SecretKey<'node'> }> {\r\n return $createSecretKey(secret, options);\r\n}\r\n\r\n/**\r\n * Derives a `SecretKey` from the provided string for encryption/decryption (throwing).\r\n *\r\n * Uses HKDF to derive a key from the input string.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * Imagine you want to create a special key for future use to lock your treasure box (data).\r\n * So, you stir in some secret ingredients (like salt and info) to make sure your key is one-of-a-kind.\r\n *\r\n * @param secret - The input string to derive the `SecretKey` from.\r\n * @param options.algorithm - The encryption algorithm to use (default: `'aes256gcm'`).\r\n * @param options.digest - The hash algorithm for HKDF (default: `'sha256'`).\r\n * @param options.salt - A salt string (default: `'cipher-kit-salt'`, must be ≥ 8 chars).\r\n * @param options.info - An info string (default: `'cipher-kit'`).\r\n * @returns The derived `SecretKey`.\r\n * @throws {Error} If key derivation fails.\r\n */\r\nexport function createSecretKey(secret: string, options: CreateSecretKeyOptions = {}): SecretKey<'node'> {\r\n const { result, error } = $createSecretKey(secret, options);\r\n if (error) throw new Error($fmtResultErr(error));\r\n return result;\r\n}\r\n\r\n/**\r\n * Safely encrypts a UTF-8 string using the provided `SecretKey` (non-throwing).\r\n *\r\n * Output format: \"iv.cipher.tag.\"\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * You scramble a secret message with your special key,\r\n * creating a jumbled code that only someone with the right key can read.\r\n *\r\n * @param data - A UTF-8 string to encrypt.\r\n * @param secretKey - The `SecretKey` object used for encryption.\r\n * @param options.encoding - The encoding format for the output ciphertext (default: `'base64url'`).\r\n * @returns A `Result` containing the encrypted string in the specified format or an error.\r\n */\r\nexport function tryEncrypt(data: string, secretKey: SecretKey<'node'>, options: EncryptOptions = {}): Result<string> {\r\n return $encrypt(data, secretKey, options);\r\n}\r\n\r\n/**\r\n * Encrypts a UTF-8 string using the provided `SecretKey` (throwing).\r\n *\r\n * Output format: \"iv.cipher.tag.\"\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * You scramble a secret message with your special key,\r\n * creating a jumbled code that only someone with the right key can read.\r\n *\r\n * @param data - A UTF-8 string to encrypt.\r\n * @param secretKey - The `SecretKey` object used for encryption.\r\n * @param options.encoding - The encoding format for the output ciphertext (default: `'base64url'`).\r\n * @returns The encrypted string in the specified format.\r\n * @throws {Error} If the input data or key is invalid, or if encryption fails.\r\n */\r\nexport function encrypt(data: string, secretKey: SecretKey<'node'>, options: EncryptOptions = {}): string {\r\n const { result, error } = $encrypt(data, secretKey, options);\r\n if (error) throw new Error($fmtResultErr(error));\r\n return result;\r\n}\r\n\r\n/**\r\n * Safely decrypts the input string using the provided `SecretKey` (non-throwing).\r\n *\r\n * Expects input in the format \"iv.cipher.tag.\" and returns the decrypted UTF-8 string.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * You take a scrambled secret message and use your special key to unscramble it,\r\n * revealing the original message inside.\r\n *\r\n * @param encrypted - The input string to decrypt, in the format \"iv.cipher.tag.\".\r\n * @param secretKey - The `SecretKey` object used for decryption.\r\n * @param options.encoding - The encoding format for the input ciphertext (default: `'base64url'`).\r\n * @returns A `Result` containing the decrypted UTF-8 string or an error.\r\n */\r\nexport function tryDecrypt(\r\n encrypted: string,\r\n secretKey: SecretKey<'node'>,\r\n options: DecryptOptions = {},\r\n): Result<string> {\r\n return $decrypt(encrypted, secretKey, options);\r\n}\r\n\r\n/**\r\n * Decrypts the input string using the provided `SecretKey` (throwing).\r\n *\r\n * Expects input in the format \"iv.cipher.tag.\" and returns the decrypted UTF-8 string.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * You take a scrambled secret message and use your special key to unscramble it,\r\n * revealing the original message inside.\r\n *\r\n * @param encrypted - The input string to decrypt, in the format \"iv.cipher.tag.\".\r\n * @param secretKey - The `SecretKey` object used for decryption.\r\n * @param options.encoding - The encoding format for the input ciphertext (default: `'base64url'`).\r\n * @returns The decrypted UTF-8 string.\r\n * @throws {Error} If the input data or key is invalid, or if decryption fails.\r\n */\r\nexport function decrypt(encrypted: string, secretKey: SecretKey<'node'>, options: DecryptOptions = {}): string {\r\n const { result, error } = $decrypt(encrypted, secretKey, options);\r\n if (error) throw new Error($fmtResultErr(error));\r\n return result;\r\n}\r\n\r\n/**\r\n * Safely encrypts a plain object using the provided `SecretKey` (non-throwing).\r\n *\r\n * Only plain objects (POJOs) are accepted. Class instances, Maps, Sets, etc. are rejected.\r\n *\r\n * Output format: \"iv.cipher.tag.\"\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * Imagine you have a toy box (an object) that you want to keep secret.\r\n * So, you take a picture of your toy box (convert it to JSON), and scramble that with\r\n * your special key, creating a jumbled code that only someone with the right key can read.\r\n *\r\n * @param data - A plain object to encrypt.\r\n * @param secretKey - The `SecretKey` object used for encryption.\r\n * @param options.encoding - The encoding format for the output ciphertext (default: `'base64url'`).\r\n * @returns A `Result` containing the encrypted string in the specified format or an error.\r\n */\r\nexport function tryEncryptObj<T extends object = Record<string, unknown>>(\r\n data: T,\r\n secretKey: SecretKey<'node'>,\r\n options: EncryptOptions = {},\r\n): Result<string> {\r\n return $encryptObj(data, secretKey, options);\r\n}\r\n\r\n/**\r\n * Encrypts a plain object using the provided `SecretKey` (throwing).\r\n *\r\n * Only plain objects (POJOs) are accepted. Class instances, Maps, Sets, etc. are rejected.\r\n *\r\n * Output format: \"iv.cipher.tag.\"\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * Imagine you have a toy box (an object) that you want to keep secret.\r\n * So, you take a picture of your toy box (convert it to JSON), and scramble that with\r\n * your special key, creating a jumbled code that only someone with the right key can read.\r\n *\r\n * @param data - A plain object to encrypt.\r\n * @param secretKey - The `SecretKey` object used for encryption.\r\n * @param options.encoding - The encoding format for the output ciphertext (default: `'base64url'`).\r\n * @returns The encrypted string in the specified format.\r\n * @throws {Error} If the input data or key is invalid, or if encryption fails.\r\n */\r\nexport function encryptObj<T extends object = Record<string, unknown>>(\r\n data: T,\r\n secretKey: SecretKey<'node'>,\r\n options: EncryptOptions = {},\r\n): string {\r\n const { result, error } = $encryptObj(data, secretKey, options);\r\n if (error) throw new Error($fmtResultErr(error));\r\n return result;\r\n}\r\n\r\n/**\r\n * Safely decrypts an encrypted JSON string into an object (non-throwing).\r\n *\r\n * Expects input in the format `\"iv.cipher.tag.\"` and returns a plain object.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * You rebuild your toy box (an object) by unscrambling the jumbled code (encrypted text),\r\n * using your special key to open it.\r\n *\r\n * @template T - The expected shape of the decrypted object.\r\n * @param encrypted - The encrypted string (format: `\"iv.cipher.tag.\"`).\r\n * @param secretKey - The `SecretKey` used for decryption.\r\n * @param options.encoding - Input ciphertext encoding (default: `'base64url'`).\r\n * @returns A `Result` with the decrypted object on success, or an error.\r\n */\r\nexport function tryDecryptObj<T extends object = Record<string, unknown>>(\r\n encrypted: string,\r\n secretKey: SecretKey<'node'>,\r\n options: DecryptOptions = {},\r\n): Result<{ result: T }> {\r\n return $decryptObj<T>(encrypted, secretKey, options);\r\n}\r\n\r\n/**\r\n * Decrypts an encrypted JSON string into an object (throwing).\r\n *\r\n * Expects input in the format `\"iv.cipher.tag.\"` and returns a plain object.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * You rebuild your toy box (an object) by unscrambling the jumbled code (encrypted text),\r\n * using your special key to open it.\r\n *\r\n * @template T - The expected shape of the decrypted object.\r\n * @param encrypted - The encrypted string (format: `\"iv.cipher.tag.\"`).\r\n * @param secretKey - The `SecretKey` used for decryption.\r\n * @param options.encoding - Input ciphertext encoding (default: `'base64url'`).\r\n * @returns The decrypted object.\r\n * @throws {Error} If decryption or JSON parsing fails.\r\n */\r\nexport function decryptObj<T extends object = Record<string, unknown>>(\r\n encrypted: string,\r\n secretKey: SecretKey<'node'>,\r\n options: DecryptOptions = {},\r\n): T {\r\n const { result, error } = $decryptObj<T>(encrypted, secretKey, options);\r\n if (error) throw new Error($fmtResultErr(error));\r\n return result;\r\n}\r\n\r\n/**\r\n * Safely hashes a UTF-8 string (non-throwing).\r\n *\r\n * Uses the selected digest (default: `'sha256'`) and returns the hash\r\n * in the chosen encoding (default: `'base64url'`).\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * Like putting something in a blender and getting a smoothie, you can’t get the original ingredients back,\r\n * but the smoothie is always the same if you use the same ingredients.\r\n *\r\n * @param data - The input string to hash.\r\n * @param options.digest - Hash algorithm (`'sha256' | 'sha384' | 'sha512'`, default: `'sha256'`).\r\n * @param options.encoding - Output encoding (`'base64' | 'base64url' | 'hex'`, default: `'base64url'`).\r\n * @returns A `Result` with the hash string or an error.\r\n */\r\nexport function tryHash(data: string, options: HashOptions = {}): Result<string> {\r\n return $hash(data, options);\r\n}\r\n\r\n/**\r\n * Hashes a UTF-8 string (throwing).\r\n *\r\n * Uses the selected digest (default: `'sha256'`) and returns the hash\r\n * in the chosen encoding (default: `'base64url'`).\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * Like putting something in a blender and getting a smoothie, you can’t get the original ingredients back,\r\n * but the smoothie is always the same if you use the same ingredients.\r\n *\r\n * @param data - The input string to hash.\r\n * @param options.digest - Hash algorithm (`'sha256' | 'sha384' | 'sha512'`; default: `'sha256'`).\r\n * @param options.encoding - Output encoding (`'base64' | 'base64url' | 'hex'`; default: `'base64url'`).\r\n * @returns The hashed string.\r\n * @throws {Error} If input is invalid or hashing fails.\r\n */\r\nexport function hash(data: string, options: HashOptions = {}): string {\r\n const { result, error } = $hash(data, options);\r\n if (error) throw new Error($fmtResultErr(error));\r\n return result;\r\n}\r\n\r\n/**\r\n * Safely hashes a password using PBKDF2 (non-throwing).\r\n *\r\n * Uses strong defaults (`sha512`, 320k iterations, 64-byte key, 16-byte salt) and\r\n * returns `{ hash, salt }` encoded (default: `'base64url'`).\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * We take your password, mix in some random salt, and stir many times.\r\n * The result is a super-secret soup that’s hard to copy.\r\n *\r\n * @param password - The password to hash.\r\n * @param options.digest - Hash algorithm (`'sha256' | 'sha384' | 'sha512'`; default: `'sha512'`).\r\n * @param options.encoding - Output encoding (`'base64' | 'base64url' | 'hex'`; default: `'base64url'`).\r\n * @param options.saltLength - Length of the random salt in bytes (default: `16` bytes, min: `8` bytes).\r\n * @param options.iterations - Number of iterations (default: `320000`, min: `1000`).\r\n * @param options.keyLength - Length of the derived key in bytes (default: `64` bytes, min: `16` bytes).\r\n * @returns A `Result` with `{ hash, salt }` or an error.\r\n */\r\nexport function tryHashPassword(\r\n password: string,\r\n options: HashPasswordOptions = {},\r\n): Result<{ hash: string; salt: string }> {\r\n return $hashPassword(password, options);\r\n}\r\n\r\n/**\r\n * Hashes a password using PBKDF2 (throwing).\r\n *\r\n * Uses strong defaults (`sha512`, 320k iterations, 64-byte key, 16-byte salt) and\r\n * returns `{ hash, salt }` encoded (default: `'base64url'`).\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * We take your password, mix in some random salt, and stir many times.\r\n * The result is a super-secret soup that’s hard to copy.\r\n *\r\n * @param password - The password to hash.\r\n * @param options.digest - Hash algorithm (`'sha256' | 'sha384' | 'sha512'`; default: `'sha512'`).\r\n * @param options.encoding - Output encoding (`'base64' | 'base64url' | 'hex'`; default: `'base64url'`).\r\n * @param options.saltLength - Length of the random salt in bytes (default: `16` bytes, min: `8` bytes).\r\n * @param options.iterations - Number of iterations (default: `320000`, min: `1000`).\r\n * @param options.keyLength - Length of the derived key in bytes (default: `64` bytes, min: `16` bytes).\r\n * @returns `{ hash, salt }` for storage.\r\n * @throws {Error} If inputs are invalid or hashing fails.\r\n */\r\nexport function hashPassword(password: string, options: HashPasswordOptions = {}): { hash: string; salt: string } {\r\n const { hash, salt, error } = $hashPassword(password, options);\r\n if (error) throw new Error($fmtResultErr(error));\r\n return { hash, salt };\r\n}\r\n\r\n/**\r\n * Verifies a password against a stored PBKDF2 hash (non-throwing).\r\n *\r\n * Re-derives the key using the same parameters and compares in constant time, to prevent timing attacks.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * We follow the same recipe as when we made the secret.\r\n * If the new soup tastes exactly the same, the password is correct.\r\n *\r\n * @param password - The plain password to verify.\r\n * @param hashedPassword - The stored hash (encoded).\r\n * @param salt - The stored salt (encoded).\r\n * @param options.digest - Hash algorithm used during hashing (`'sha256' | 'sha384' | 'sha512'`; default: `'sha512'`).\r\n * @param options.encoding - Encoding of the stored hash and salt (`'base64' | 'base64url' | 'hex'`; default: `'base64url'`).\r\n * @param options.iterations - Number of iterations used during hashing (default: `320000`).\r\n * @param options.keyLength - Length of the derived key in bytes used during hashing (default: `64` bytes).\r\n * @returns `true` if the password matches, otherwise `false`.\r\n */\r\nexport function verifyPassword(\r\n password: string,\r\n hashedPassword: string,\r\n salt: string,\r\n options: VerifyPasswordOptions = {},\r\n): boolean {\r\n return $verifyPassword(password, hashedPassword, salt, options);\r\n}\r\n\r\n/**\r\n * Safely converts a string to a Node.js `Buffer` using the specified encoding (non-throwing).\r\n *\r\n * Supported encodings: `'base64' | 'base64url' | 'hex' | 'utf8' | 'latin1'` (default: `'utf8'`).\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * This turns your words into tiny computer building blocks (bytes) so computers can work with them.\r\n *\r\n * @param data - The input string to convert.\r\n * @param inputEncoding - The encoding of the input string (default: `'utf8'`).\r\n * @returns A `Result` with `{ result: Buffer }` or an error.\r\n */\r\nexport function tryConvertStrToBytes(data: string, inputEncoding: Encoding = 'utf8'): Result<{ result: Buffer }> {\r\n return $convertStrToBytes(data, inputEncoding);\r\n}\r\n\r\n/**\r\n * Converts a string to a Node.js `Buffer` using the specified encoding (throwing).\r\n *\r\n * Supported encodings: `'base64' | 'base64url' | 'hex' | 'utf8' | 'latin1'` (default: `'utf8'`).\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * This turns your words into tiny computer building blocks (bytes) so computers can work with them.\r\n *\r\n * @param data - The input string to convert.\r\n * @param inputEncoding - The encoding of the input string (default: `'utf8'`).\r\n * @returns A `Buffer` containing the bytes.\r\n * @throws {Error} If input is invalid or conversion fails.\r\n */\r\nexport function convertStrToBytes(data: string, inputEncoding: Encoding = 'utf8'): Buffer {\r\n const { result, error } = $convertStrToBytes(data, inputEncoding);\r\n if (error) throw new Error($fmtResultErr(error));\r\n return result;\r\n}\r\n\r\n/**\r\n * Safely converts a Node.js `Buffer` to a string using the specified encoding (non-throwing).\r\n *\r\n * Supported encodings: `'base64' | 'base64url' | 'hex' | 'utf8' | 'latin1'` (default: `'utf8'`).\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * This turns the tiny computer building blocks (bytes) back into a readable sentence.\r\n *\r\n * @param data - The `Buffer` to convert.\r\n * @param outputEncoding - The output encoding (default: `'utf8'`).\r\n * @returns A `Result` with the string or an error.\r\n */\r\nexport function tryConvertBytesToStr(data: Buffer, outputEncoding: Encoding = 'utf8'): Result<string> {\r\n return $convertBytesToStr(data, outputEncoding);\r\n}\r\n\r\n/**\r\n * Converts a Node.js `Buffer` to a string using the specified encoding (throwing).\r\n *\r\n * Supported encodings: `'base64' | 'base64url' | 'hex' | 'utf8' | 'latin1'` (default: `'utf8'`).\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * This turns the tiny computer building blocks (bytes) back into a readable sentence.\r\n *\r\n * @param data - The `Buffer` to convert.\r\n * @param outputEncoding - The output encoding (default: `'utf8'`).\r\n * @returns The encoded string.\r\n * @throws {Error} If input is invalid or conversion fails.\r\n */\r\nexport function convertBytesToStr(data: Buffer, outputEncoding: Encoding = 'utf8'): string {\r\n const { result, error } = $convertBytesToStr(data, outputEncoding);\r\n if (error) throw new Error($fmtResultErr(error));\r\n return result;\r\n}\r\n\r\n/**\r\n * Safely converts text between encodings (non-throwing).\r\n *\r\n * Example: convert `'utf8'` text to `'base64url'`, or `'hex'` to `'utf8'`.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * It’s like translating your sentence from one alphabet to another.\r\n *\r\n * @param data - The input string to convert.\r\n * @param from - The current encoding of `data`.\r\n * @param to - The target encoding for `data`.\r\n * @returns A `Result` with a string or an error.\r\n */\r\nexport function tryConvertEncoding(data: string, from: Encoding, to: Encoding): Result<string> {\r\n return $convertEncoding(data, from, to);\r\n}\r\n\r\n/**\r\n * Converts text between encodings (throwing).\r\n *\r\n * Example: convert `'utf8'` text to `'base64url'`, or `'hex'` to `'utf8'`.\r\n *\r\n * ### 🍼 Explain Like I'm Five\r\n * It’s like translating your sentence from one alphabet to another.\r\n *\r\n * @param data - The input string to convert.\r\n * @param from - The current encoding of `data`.\r\n * @param to - The target encoding for `data`.\r\n * @returns The converted string.\r\n * @throws {Error} If encodings are invalid or conversion fails.\r\n */\r\nexport function convertEncoding(data: string, from: Encoding, to: Encoding): string {\r\n const { result, error } = $convertEncoding(data, from, to);\r\n if (error) throw new Error($fmtResultErr(error));\r\n return result;\r\n}\r\n","import { Buffer } from 'node:buffer';\r\nimport { ENCODING } from '~/helpers/consts';\r\nimport { $err, $fmtError, $ok, type Result } from '~/helpers/error';\r\nimport type { Encoding } from '~/helpers/types';\r\nimport { $isStr } from '~/helpers/validate';\r\n\r\nexport function $convertStrToBytes(data: string, inputEncoding: Encoding = 'utf8'): Result<{ result: Buffer }> {\r\n if (!$isStr(data)) {\r\n return $err({\r\n msg: 'Crypto NodeJS API - String to Bytes: Empty data',\r\n desc: 'Data must be a non-empty string',\r\n });\r\n }\r\n if (!ENCODING.includes(inputEncoding)) {\r\n return $err({\r\n msg: `Crypto NodeJS API - String to Bytes: Unsupported encoding: ${inputEncoding}`,\r\n desc: 'Use base64, base64url, hex, utf8, or latin1',\r\n });\r\n }\r\n try {\r\n return $ok({ result: Buffer.from(data, inputEncoding) });\r\n } catch (error) {\r\n return $err({ msg: 'Crypto NodeJS API - String to Bytes: Failed to convert data', desc: $fmtError(error) });\r\n }\r\n}\r\n\r\nexport function $convertBytesToStr(data: Buffer, outputEncoding: Encoding = 'utf8'): Result<string> {\r\n if (!(data instanceof Buffer)) {\r\n return $err({\r\n msg: 'Crypto NodeJS API - Bytes to String: Invalid data type',\r\n desc: 'Data must be a Buffer',\r\n });\r\n }\r\n if (!ENCODING.includes(outputEncoding)) {\r\n return $err({\r\n msg: `Crypto NodeJS API - Bytes to String: Unsupported encoding: ${outputEncoding}`,\r\n desc: 'Use base64, base64url, hex, utf8, or latin1',\r\n });\r\n }\r\n try {\r\n return $ok(Buffer.from(data).toString(outputEncoding));\r\n } catch (error) {\r\n return $err({ msg: 'Crypto NodeJS API - Bytes to String: Failed to convert data', desc: $fmtError(error) });\r\n }\r\n}\r\n\r\nexport function $convertEncoding(data: string, from: Encoding, to: Encoding): Result<string> {\r\n if (!$isStr(data)) {\r\n return $err({\r\n msg: 'Crypto NodeJS API - Convert Format: Empty data',\r\n desc: 'Data must be a non-empty string',\r\n });\r\n }\r\n\r\n if (!ENCODING.includes(from) || !ENCODING.includes(to)) {\r\n return $err({\r\n msg: `Crypto NodeJS API - Convert Format: Unsupported encoding: from ${from} to ${to}`,\r\n desc: 'Use base64, base64url, hex, utf8, or latin1',\r\n });\r\n }\r\n\r\n const bytes = $convertStrToBytes(data, from);\r\n if (bytes.error) return $err({ msg: bytes.error.message, desc: bytes.error.description });\r\n\r\n const str = $convertBytesToStr(bytes.result, to);\r\n if (str.error) return $err({ msg: str.error.message, desc: str.error.description });\r\n\r\n return $ok({ result: str.result });\r\n}\r\n","import { Buffer } from 'node:buffer';\r\nimport nodeCrypto from 'node:crypto';\r\nimport { CIPHER_ENCODING, DIGEST_ALGORITHMS, ENCRYPTION_ALGORITHMS } from '~/helpers/consts';\r\nimport { $err, $fmtError, $fmtResultErr, $ok, type Result, title } from '~/helpers/error';\r\nimport { $parseToObj, $stringifyObj } from '~/helpers/object';\r\nimport type {\r\n CreateSecretKeyOptions,\r\n DecryptOptions,\r\n EncryptOptions,\r\n HashOptions,\r\n HashPasswordOptions,\r\n SecretKey,\r\n VerifyPasswordOptions,\r\n} from '~/helpers/types';\r\nimport { $isSecretKey, $isStr, matchPattern } from '~/helpers/validate';\r\nimport { $convertBytesToStr, $convertStrToBytes } from './node-encode';\r\n\r\nexport function $generateUuid(): Result<string> {\r\n try {\r\n return $ok(nodeCrypto.randomUUID());\r\n } catch (error) {\r\n return $err({ msg: `${title('node', 'UUID Generation')}: Failed to generate UUID`, desc: $fmtError(error) });\r\n }\r\n}\r\n\r\nexport function $createSecretKey(\r\n secret: string,\r\n options: CreateSecretKeyOptions = {},\r\n): Result<{ result: SecretKey<'node'> }> {\r\n if (!$isStr(secret)) {\r\n return $err({ msg: `${title('node', 'Key Generation')}: Empty Secret`, desc: 'Secret must be a non-empty string' });\r\n }\r\n\r\n const algorithm = options.algorithm ?? 'aes256gcm';\r\n if (!(algorithm in ENCRYPTION_ALGORITHMS)) {\r\n return $err({\r\n msg: `${title('node', 'Key Generation')}: Unsupported algorithm: ${algorithm}`,\r\n desc: `Supported algorithms are: ${Object.keys(ENCRYPTION_ALGORITHMS).join(', ')}`,\r\n });\r\n }\r\n\r\n const digest = options.digest ?? 'sha256';\r\n if (!(digest in DIGEST_ALGORITHMS)) {\r\n return $err({\r\n msg: `${title('node', 'Key Generation')}: Unsupported digest: ${digest}`,\r\n desc: `Supported digests are: ${Object.keys(DIGEST_ALGORITHMS).join(', ')}`,\r\n });\r\n }\r\n\r\n const salt = options.salt ?? 'cipher-kit-salt';\r\n if (!$isStr(salt, 8)) {\r\n return $err({\r\n msg: `${title('node', 'Key Generation')}: Weak salt`,\r\n desc: 'Salt must be a non-empty string with at least 8 characters',\r\n });\r\n }\r\n\r\n const info = options.info ?? 'cipher-kit';\r\n if (!$isStr(info)) {\r\n return $err({\r\n msg: `${title('node', 'Key Generation')}: Invalid info`,\r\n desc: 'Info must be a non-empty string',\r\n });\r\n }\r\n\r\n const encryptAlgo = ENCRYPTION_ALGORITHMS[algorithm];\r\n const digestAlgo = DIGEST_ALGORITHMS[digest];\r\n\r\n try {\r\n const derivedKey = nodeCrypto.hkdfSync(\r\n digestAlgo.node,\r\n secret.normalize('NFKC'),\r\n salt.normalize('NFKC'),\r\n info.normalize('NFKC'),\r\n encryptAlgo.keyBytes,\r\n );\r\n const key = nodeCrypto.createSecretKey(Buffer.from(derivedKey));\r\n const secretKey = Object.freeze({\r\n platform: 'node',\r\n digest: digest,\r\n algorithm: algorithm,\r\n key: key,\r\n }) as SecretKey<'node'>;\r\n\r\n return $ok({ result: secretKey });\r\n } catch (error) {\r\n return $err({ msg: `${title('node', 'Key Generation')}: Failed to create secret key`, desc: $fmtError(error) });\r\n }\r\n}\r\n\r\nexport function $encrypt(data: string, secretKey: SecretKey<'node'>, options: EncryptOptions = {}): Result<string> {\r\n if (!$isStr(data)) {\r\n return $err({\r\n msg: `${title('node', 'Encryption')}: Empty data for encryption`,\r\n desc: 'Data must be a non-empty string',\r\n });\r\n }\r\n\r\n const encoding = options.encoding ?? 'base64url';\r\n if (!CIPHER_ENCODING.includes(encoding)) {\r\n return $err({\r\n msg: `${title('node', 'Encryption')}: Unsupported output encoding: ${encoding}`,\r\n desc: 'Use base64, base64url, or hex',\r\n });\r\n }\r\n\r\n const injectedKey = $isSecretKey(secretKey, 'node');\r\n if (!injectedKey) {\r\n return $err({\r\n msg: `${title('node', 'Encryption')}: Invalid Secret Key`,\r\n desc: 'Expected a Node SecretKey',\r\n });\r\n }\r\n\r\n const { result, error } = $convertStrToBytes(data, 'utf8');\r\n if (error) return $err(error);\r\n\r\n try {\r\n const iv = nodeCrypto.randomBytes(injectedKey.injected.ivLength);\r\n const cipher = nodeCrypto.createCipheriv(injectedKey.injected.node, injectedKey.key, iv);\r\n const encrypted = Buffer.concat([cipher.update(result), cipher.final()]);\r\n const tag = cipher.getAuthTag();\r\n\r\n const ivStr = $convertBytesToStr(iv, encoding);\r\n const cipherStr = $convertBytesToStr(encrypted, encoding);\r\n const tagStr = $convertBytesToStr(tag, encoding);\r\n\r\n if (ivStr.error || cipherStr.error || tagStr.error) {\r\n return $err({\r\n msg: 'Crypto NodeJS API - Encryption: Failed to convert IV or encrypted data or tag',\r\n desc: `Conversion error: ${$fmtResultErr(ivStr.error || cipherStr.error || tagStr.error)}`,\r\n });\r\n }\r\n\r\n return $ok(`${ivStr.result}.${cipherStr.result}.${tagStr.result}.`);\r\n } catch (error) {\r\n return $err({ msg: `${title('node', 'Encryption')}: Failed to encrypt data`, desc: $fmtError(error) });\r\n }\r\n}\r\n\r\nexport function $decrypt(\r\n encrypted: string,\r\n secretKey: SecretKey<'node'>,\r\n options: DecryptOptions = {},\r\n): Result<string> {\r\n if (matchPattern(encrypted, 'node') === false) {\r\n return $err({\r\n msg: `${title('node', 'Decryption')}: Invalid encrypted data format`,\r\n desc: 'Encrypted data must be in the format \"iv.cipher.tag.\"',\r\n });\r\n }\r\n\r\n const encoding = options.encoding ?? 'base64url';\r\n if (!CIPHER_ENCODING.includes(encoding)) {\r\n return $err({\r\n msg: `${title('node', 'Decryption')}: Unsupported input encoding: ${encoding}`,\r\n desc: 'Use base64, base64url, or hex',\r\n });\r\n }\r\n\r\n const [iv, cipher, tag] = encrypted.split('.', 4);\r\n if (!$isStr(iv) || !$isStr(cipher) || !$isStr(tag)) {\r\n return $err({\r\n msg: `${title('node', 'Decryption')}: Invalid encrypted data`,\r\n desc: 'Encrypted data must contain valid IV, encrypted data, and tag components',\r\n });\r\n }\r\n\r\n const injectedKey = $isSecretKey(secretKey, 'node');\r\n if (!injectedKey) {\r\n return $err({\r\n msg: 'Crypto NodeJS API - Decryption: Invalid Secret Key',\r\n desc: 'Expected a Node SecretKey',\r\n });\r\n }\r\n\r\n const ivBytes = $convertStrToBytes(iv, encoding);\r\n const cipherBytes = $convertStrToBytes(cipher, encoding);\r\n const tagBytes = $convertStrToBytes(tag, encoding);\r\n\r\n if (ivBytes.error || cipherBytes.error || tagBytes.error) {\r\n return $err({\r\n msg: `${title('node', 'Decryption')}: Failed to convert IV or encrypted data or tag`,\r\n desc: `Conversion error: ${$fmtResultErr(ivBytes.error || cipherBytes.error || tagBytes.error)}`,\r\n });\r\n }\r\n\r\n try {\r\n const decipher = nodeCrypto.createDecipheriv(injectedKey.injected.node, injectedKey.key, ivBytes.result);\r\n decipher.setAuthTag(tagBytes.result);\r\n const decrypted = Buffer.concat([decipher.update(cipherBytes.result), decipher.final()]);\r\n\r\n return $convertBytesToStr(decrypted, 'utf8');\r\n } catch (error) {\r\n return $err({ msg: `${title('node', 'Decryption')}: Failed to decrypt data`, desc: $fmtError(error) });\r\n }\r\n}\r\nexport function $encryptObj<T extends object = Record<string, unknown>>(\r\n data: T,\r\n secretKey: SecretKey<'node'>,\r\n options: EncryptOptions = {},\r\n): Result<string> {\r\n const { result, error } = $stringifyObj(data);\r\n if (error) return $err(error);\r\n return $encrypt(result, secretKey, options);\r\n}\r\n\r\nexport function $decryptObj<T extends object = Record<string, unknown>>(\r\n encrypted: string,\r\n secretKey: SecretKey<'node'>,\r\n options: DecryptOptions = {},\r\n): Result<{ result: T }> {\r\n const { result, error } = $decrypt(encrypted, secretKey, options);\r\n if (error) return $err(error);\r\n return $parseToObj<T>(result);\r\n}\r\n\r\nexport function $hash(data: string, options: HashOptions = {}): Result<string> {\r\n if (!$isStr(data)) {\r\n return $err({\r\n msg: `${title('node', 'Hashing')}: Empty data for hashing`,\r\n desc: 'Data must be a non-empty string',\r\n });\r\n }\r\n\r\n const encoding = options.encoding ?? 'base64url';\r\n if (!CIPHER_ENCODING.includes(encoding)) {\r\n return $err({\r\n msg: `${title('node', 'Hashing')}: Unsupported output encoding: ${encoding}`,\r\n desc: 'Use base64, base64url, or hex',\r\n });\r\n }\r\n\r\n const digest = options.digest ?? 'sha256';\r\n if (!(digest in DIGEST_ALGORITHMS)) {\r\n return $err({\r\n msg: `${title('node', 'Hashing')}: Unsupported digest: ${digest}`,\r\n desc: `Supported digests are: ${Object.keys(DIGEST_ALGORITHMS).join(', ')}`,\r\n });\r\n }\r\n const digestAlgo = DIGEST_ALGORITHMS[digest];\r\n\r\n const { result, error } = $convertStrToBytes(data, 'utf8');\r\n if (error) return $err(error);\r\n\r\n try {\r\n const hashed = nodeCrypto.createHash(digestAlgo.node).update(result).digest();\r\n return $convertBytesToStr(hashed, encoding);\r\n } catch (error) {\r\n return $err({ msg: `${title('node', 'Hashing')}: Failed to hash data with Crypto NodeJS`, desc: $fmtError(error) });\r\n }\r\n}\r\n\r\nexport function $hashPassword(\r\n password: string,\r\n options: HashPasswordOptions = {},\r\n): Result<{ hash: string; salt: string }> {\r\n if (!$isStr(password)) {\r\n return $err({\r\n msg: `${title('node', 'Password Hashing')}: Empty password for hashing`,\r\n desc: 'Password must be a non-empty string',\r\n });\r\n }\r\n\r\n const digest = options.digest ?? 'sha512';\r\n if (!(digest in DIGEST_ALGORITHMS)) {\r\n return $err({\r\n msg: `${title('node', 'Password Hashing')}: Unsupported digest: ${digest}`,\r\n desc: `Supported digests are: ${Object.keys(DIGEST_ALGORITHMS).join(', ')}`,\r\n });\r\n }\r\n const digestAlgo = DIGEST_ALGORITHMS[digest];\r\n\r\n const encoding = options.encoding ?? 'base64url';\r\n if (!CIPHER_ENCODING.includes(encoding)) {\r\n return $err({\r\n msg: `${title('node', 'Password Hashing')}: Unsupported encoding: ${encoding}`,\r\n desc: 'Use base64, base64url, or hex',\r\n });\r\n }\r\n\r\n const saltLength = options.saltLength ?? 16;\r\n if (typeof saltLength !== 'number' || saltLength < 8) {\r\n return $err({\r\n msg: `${title('node', 'Password Hashing')}: Weak salt length`,\r\n desc: 'Salt length must be a number and at least 8 bytes (recommended 16 or more)',\r\n });\r\n }\r\n\r\n const iterations = options.iterations ?? 320_000;\r\n if (typeof iterations !== 'number' || iterations < 1000) {\r\n return $err({\r\n msg: `${title('node', 'Password Hashing')}: Weak iterations count`,\r\n desc: 'Iterations must be a number and at least 1000 (recommended 320,000 or more)',\r\n });\r\n }\r\n\r\n const keyLength = options.keyLength ?? 64;\r\n if (typeof keyLength !== 'number' || keyLength < 16) {\r\n return $err({\r\n msg: `${title('node', 'Password Hashing')}: Invalid key length`,\r\n desc: 'Key length must be a number and at least 16 bytes (recommended 64 or more)',\r\n });\r\n }\r\n\r\n try {\r\n const salt = nodeCrypto.randomBytes(saltLength);\r\n const hash = nodeCrypto.pbkdf2Sync(password.normalize('NFKC'), salt, iterations, keyLength, digestAlgo.node);\r\n\r\n return $ok({ salt: salt.toString(encoding), hash: hash.toString(encoding) });\r\n } catch (error) {\r\n return $err({ msg: `${title('node', 'Password Hashing')}: Failed to hash password`, desc: $fmtError(error) });\r\n }\r\n}\r\n\r\nexport function $verifyPassword(\r\n password: string,\r\n hashedPassword: string,\r\n salt: string,\r\n options: VerifyPasswordOptions = {},\r\n): boolean {\r\n if (!$isStr(password) || !$isStr(hashedPassword) || !$isStr(salt)) return false;\r\n\r\n const digest = options.digest ?? 'sha512';\r\n if (!(digest in DIGEST_ALGORITHMS)) return false;\r\n const digestAlgo = DIGEST_ALGORITHMS[digest];\r\n\r\n const encoding = options.encoding ?? 'base64url';\r\n if (!CIPHER_ENCODING.includes(encoding)) return false;\r\n\r\n const iterations = options.iterations ?? 320_000;\r\n if (typeof iterations !== 'number' || iterations < 1000) return false;\r\n\r\n const keyLength = options.keyLength ?? 64;\r\n if (typeof keyLength !== 'number' || keyLength < 16) return false;\r\n\r\n const saltBytes = $convertStrToBytes(salt, encoding);\r\n if (saltBytes.error) return false;\r\n\r\n const hashedPasswordBytes = $convertStrToBytes(hashedPassword, encoding);\r\n if (hashedPasswordBytes.error) return false;\r\n\r\n try {\r\n return nodeCrypto.timingSafeEqual(\r\n nodeCrypto.pbkdf2Sync(password.normalize('NFKC'), saltBytes.result, iterations, keyLength, digestAlgo.node),\r\n hashedPasswordBytes.result,\r\n );\r\n } catch {\r\n return false;\r\n }\r\n}\r\n"]}
|