@alibarbar/common 1.0.10 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/algorithm.cjs +1 -1
  2. package/dist/algorithm.js +1 -1
  3. package/dist/array.cjs +1 -1
  4. package/dist/array.js +1 -1
  5. package/dist/color.cjs +1 -1
  6. package/dist/color.js +1 -1
  7. package/dist/crypto.cjs +109 -1
  8. package/dist/crypto.d.mts +48 -1
  9. package/dist/crypto.d.ts +48 -1
  10. package/dist/crypto.js +104 -2
  11. package/dist/data-structure.cjs +1 -1
  12. package/dist/data-structure.js +1 -1
  13. package/dist/date.cjs +1 -1
  14. package/dist/date.js +1 -1
  15. package/dist/dom.cjs +1 -1
  16. package/dist/dom.js +1 -1
  17. package/dist/file.cjs +1 -1
  18. package/dist/file.js +1 -1
  19. package/dist/i18n.cjs +1 -1
  20. package/dist/i18n.js +1 -1
  21. package/dist/index.cjs +848 -415
  22. package/dist/index.d.mts +3 -3
  23. package/dist/index.d.ts +3 -3
  24. package/dist/index.js +838 -413
  25. package/dist/network.cjs +1 -1
  26. package/dist/network.js +1 -1
  27. package/dist/number.cjs +1 -1
  28. package/dist/number.js +1 -1
  29. package/dist/object.cjs +1 -1
  30. package/dist/object.js +1 -1
  31. package/dist/performance.cjs +1 -1
  32. package/dist/performance.js +1 -1
  33. package/dist/storage.cjs +509 -104
  34. package/dist/storage.d.mts +50 -73
  35. package/dist/storage.d.ts +50 -73
  36. package/dist/storage.js +505 -102
  37. package/dist/string.cjs +1 -1
  38. package/dist/string.js +1 -1
  39. package/dist/tracking.cjs +1 -1
  40. package/dist/tracking.js +1 -1
  41. package/dist/transform.cjs +1 -1
  42. package/dist/transform.js +1 -1
  43. package/dist/upload.cjs +2 -2
  44. package/dist/upload.d.mts +1 -1
  45. package/dist/upload.d.ts +1 -1
  46. package/dist/upload.js +2 -2
  47. package/dist/url.cjs +1 -1
  48. package/dist/url.js +1 -1
  49. package/dist/validation.cjs +1 -1
  50. package/dist/validation.js +1 -1
  51. package/package.json +3 -1
  52. /package/dist/{upload-DchqyDBQ.d.mts → index-DchqyDBQ.d.mts} +0 -0
  53. /package/dist/{upload-DchqyDBQ.d.ts → index-DchqyDBQ.d.ts} +0 -0
package/dist/storage.cjs CHANGED
@@ -1,38 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __esm = (fn, res) => function __init() {
6
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
7
- };
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
-
13
- // src/helper/crypto.ts
14
- var crypto_exports = {};
15
- __export(crypto_exports, {
16
- base64Decode: () => base64Decode,
17
- base64Encode: () => base64Encode,
18
- exportPrivateKey: () => exportPrivateKey,
19
- exportPublicKey: () => exportPublicKey,
20
- generateRSAKeyPair: () => generateRSAKeyPair,
21
- generateRandomString: () => generateRandomString,
22
- generateUUID: () => generateUUID,
23
- hash: () => hash,
24
- importPrivateKey: () => importPrivateKey,
25
- importPublicKey: () => importPublicKey,
26
- rsaDecrypt: () => rsaDecrypt,
27
- rsaEncrypt: () => rsaEncrypt,
28
- sha256: () => sha256
29
- });
30
- async function sha256(data) {
31
- const buffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
32
- const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
33
- const hashArray = Array.from(new Uint8Array(hashBuffer));
34
- return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
35
- }
3
+ // src/helper/crypto/index.ts
36
4
  function base64Encode(data) {
37
5
  if (typeof data === "string") {
38
6
  return btoa(unescape(encodeURIComponent(data)));
@@ -51,16 +19,6 @@ function base64Decode(data) {
51
19
  throw new Error("Invalid Base64 string");
52
20
  }
53
21
  }
54
- function generateUUID() {
55
- if (typeof crypto !== "undefined" && crypto.randomUUID) {
56
- return crypto.randomUUID();
57
- }
58
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
59
- const r = Math.random() * 16 | 0;
60
- const v = c === "x" ? r : r & 3 | 8;
61
- return v.toString(16);
62
- });
63
- }
64
22
  function generateRandomString(length, charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") {
65
23
  let result = "";
66
24
  for (let i = 0; i < length; i++) {
@@ -68,15 +26,6 @@ function generateRandomString(length, charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde
68
26
  }
69
27
  return result;
70
28
  }
71
- function hash(data) {
72
- let hashValue = 0;
73
- for (let i = 0; i < data.length; i++) {
74
- const char = data.charCodeAt(i);
75
- hashValue = (hashValue << 5) - hashValue + char;
76
- hashValue = hashValue & hashValue;
77
- }
78
- return Math.abs(hashValue);
79
- }
80
29
  async function generateRSAKeyPair(modulusLength = 2048) {
81
30
  if (typeof crypto === "undefined" || !crypto.subtle) {
82
31
  throw new Error("Web Crypto API is not available");
@@ -197,33 +146,428 @@ async function importPrivateKey(keyData) {
197
146
  ["decrypt"]
198
147
  );
199
148
  }
200
- var init_crypto = __esm({
201
- "src/helper/crypto.ts"() {
149
+ async function generateHMACKey() {
150
+ if (typeof crypto === "undefined" || !crypto.subtle) {
151
+ throw new Error("Web Crypto API is not available");
202
152
  }
203
- });
153
+ return crypto.subtle.generateKey(
154
+ {
155
+ name: "HMAC",
156
+ hash: "SHA-256"
157
+ },
158
+ true,
159
+ ["sign", "verify"]
160
+ );
161
+ }
162
+ async function computeHMAC(data, key) {
163
+ if (typeof crypto === "undefined" || !crypto.subtle) {
164
+ throw new Error("Web Crypto API is not available");
165
+ }
166
+ const buffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
167
+ const signature = await crypto.subtle.sign("HMAC", key, buffer);
168
+ return base64Encode(signature);
169
+ }
170
+ async function verifyHMAC(data, signature, key) {
171
+ if (typeof crypto === "undefined" || !crypto.subtle) {
172
+ throw new Error("Web Crypto API is not available");
173
+ }
174
+ try {
175
+ const dataBuffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
176
+ const signatureBuffer = new Uint8Array(
177
+ atob(signature).split("").map((char) => char.charCodeAt(0))
178
+ );
179
+ return await crypto.subtle.verify("HMAC", key, signatureBuffer, dataBuffer);
180
+ } catch {
181
+ return false;
182
+ }
183
+ }
184
+ async function deriveKeyFromPassword(password, salt, iterations = 1e5, keyLength = 256) {
185
+ if (typeof crypto === "undefined" || !crypto.subtle) {
186
+ throw new Error("Web Crypto API is not available");
187
+ }
188
+ const saltBuffer = typeof salt === "string" ? new TextEncoder().encode(salt) : salt;
189
+ const passwordKey = await crypto.subtle.importKey(
190
+ "raw",
191
+ new TextEncoder().encode(password),
192
+ "PBKDF2",
193
+ false,
194
+ ["deriveBits", "deriveKey"]
195
+ );
196
+ return crypto.subtle.deriveKey(
197
+ {
198
+ name: "PBKDF2",
199
+ salt: saltBuffer,
200
+ iterations,
201
+ hash: "SHA-256"
202
+ },
203
+ passwordKey,
204
+ {
205
+ name: "AES-GCM",
206
+ length: keyLength
207
+ },
208
+ false,
209
+ ["encrypt", "decrypt"]
210
+ );
211
+ }
212
+ async function aesGCMEncrypt(data, key) {
213
+ if (typeof crypto === "undefined" || !crypto.subtle) {
214
+ throw new Error("Web Crypto API is not available");
215
+ }
216
+ const dataBuffer = typeof data === "string" ? new TextEncoder().encode(data) : data;
217
+ const iv = crypto.getRandomValues(new Uint8Array(12));
218
+ const encrypted = await crypto.subtle.encrypt(
219
+ {
220
+ name: "AES-GCM",
221
+ iv
222
+ },
223
+ key,
224
+ dataBuffer
225
+ );
226
+ return {
227
+ encrypted: base64Encode(encrypted),
228
+ iv: base64Encode(iv.buffer)
229
+ };
230
+ }
231
+ async function aesGCMDecrypt(encryptedData, iv, key) {
232
+ if (typeof crypto === "undefined" || !crypto.subtle) {
233
+ throw new Error("Web Crypto API is not available");
234
+ }
235
+ const encryptedBuffer = new Uint8Array(
236
+ atob(encryptedData).split("").map((char) => char.charCodeAt(0))
237
+ );
238
+ const ivBuffer = new Uint8Array(
239
+ atob(iv).split("").map((char) => char.charCodeAt(0))
240
+ );
241
+ const decrypted = await crypto.subtle.decrypt(
242
+ {
243
+ name: "AES-GCM",
244
+ iv: ivBuffer
245
+ },
246
+ key,
247
+ encryptedBuffer
248
+ );
249
+ return new TextDecoder().decode(decrypted);
250
+ }
204
251
 
205
- // src/browser/storage.ts
206
- init_crypto();
252
+ // src/browser/SecureStorage/index.ts
207
253
  var globalKeyPair = null;
254
+ var globalHMACKey = null;
255
+ var keyPairInitialized = false;
256
+ var initOptions = {
257
+ autoGenerateKeys: true,
258
+ persistKeys: false,
259
+ keyStorageKey: void 0,
260
+ // 将自动生成随机键名
261
+ keyEncryptionPassword: void 0,
262
+ pbkdf2Iterations: 1e5,
263
+ keyModulusLength: 2048,
264
+ enableHMAC: true,
265
+ enableTimestampValidation: true,
266
+ timestampMaxAge: 7 * 24 * 60 * 60 * 1e3,
267
+ // 7 天
268
+ isProduction: false
269
+ };
270
+ var actualKeyStorageKey = null;
271
+ var keyUsageCount = 0;
272
+ var initializationPromise = null;
273
+ function generateKeyStorageKey() {
274
+ return `_sk_${generateRandomString(32)}_${Date.now()}`;
275
+ }
276
+ async function initializeStorageKeys(options = {}) {
277
+ if (options.forceReinitialize) {
278
+ globalKeyPair = null;
279
+ globalHMACKey = null;
280
+ keyPairInitialized = false;
281
+ actualKeyStorageKey = null;
282
+ keyUsageCount = 0;
283
+ initializationPromise = null;
284
+ } else if (keyPairInitialized && globalKeyPair) {
285
+ initOptions = { ...initOptions, ...options };
286
+ return;
287
+ }
288
+ initOptions = { ...initOptions, ...options };
289
+ if (initOptions.keyStorageKey) {
290
+ actualKeyStorageKey = initOptions.keyStorageKey;
291
+ } else {
292
+ actualKeyStorageKey = generateKeyStorageKey();
293
+ }
294
+ if (initOptions.persistKeys && typeof window !== "undefined" && window.localStorage) {
295
+ try {
296
+ const storedKeys = window.localStorage.getItem(actualKeyStorageKey);
297
+ if (storedKeys) {
298
+ const keyData = JSON.parse(storedKeys);
299
+ if (keyData.encrypted && keyData.privateKeyEncrypted && keyData.salt) {
300
+ if (!initOptions.keyEncryptionPassword) {
301
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
302
+ console.error("Encrypted keys found but no password provided");
303
+ }
304
+ throw new Error("Password required to decrypt stored keys");
305
+ }
306
+ const saltArray = new Uint8Array(
307
+ atob(keyData.salt).split("").map((char) => char.charCodeAt(0))
308
+ );
309
+ const iterations = keyData.pbkdf2Iterations || initOptions.pbkdf2Iterations;
310
+ const derivedKey = await deriveKeyFromPassword(
311
+ initOptions.keyEncryptionPassword,
312
+ saltArray.buffer,
313
+ iterations
314
+ );
315
+ const decryptedPrivateKey = await aesGCMDecrypt(
316
+ keyData.privateKeyEncrypted,
317
+ keyData.iv,
318
+ derivedKey
319
+ );
320
+ globalKeyPair = {
321
+ publicKey: await importPublicKey(keyData.publicKey),
322
+ privateKey: await importPrivateKey(decryptedPrivateKey)
323
+ };
324
+ } else if (keyData.publicKey && keyData.privateKey) {
325
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
326
+ console.warn(
327
+ "\u26A0\uFE0F SECURITY WARNING: Loading unencrypted keys from storage. Consider re-initializing with password encryption."
328
+ );
329
+ }
330
+ globalKeyPair = {
331
+ publicKey: await importPublicKey(keyData.publicKey),
332
+ privateKey: await importPrivateKey(keyData.privateKey)
333
+ };
334
+ }
335
+ if (globalKeyPair) {
336
+ keyPairInitialized = true;
337
+ if (initOptions.enableHMAC && !globalHMACKey) {
338
+ globalHMACKey = await generateHMACKey();
339
+ }
340
+ return;
341
+ }
342
+ }
343
+ } catch (error) {
344
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
345
+ console.warn("Failed to load persisted keys, will generate new ones");
346
+ }
347
+ }
348
+ }
349
+ if (initOptions.autoGenerateKeys && !globalKeyPair) {
350
+ try {
351
+ globalKeyPair = await generateRSAKeyPair(initOptions.keyModulusLength);
352
+ if (initOptions.enableHMAC && !globalHMACKey) {
353
+ globalHMACKey = await generateHMACKey();
354
+ }
355
+ keyPairInitialized = true;
356
+ keyUsageCount = 0;
357
+ if (initOptions.persistKeys && typeof window !== "undefined" && window.localStorage) {
358
+ try {
359
+ const publicKeyStr = await exportPublicKey(globalKeyPair.publicKey);
360
+ if (initOptions.keyEncryptionPassword) {
361
+ const privateKeyStr = await exportPrivateKey(globalKeyPair.privateKey);
362
+ const salt = crypto.getRandomValues(new Uint8Array(16));
363
+ const derivedKey = await deriveKeyFromPassword(
364
+ initOptions.keyEncryptionPassword,
365
+ salt.buffer,
366
+ initOptions.pbkdf2Iterations
367
+ );
368
+ const { encrypted, iv } = await aesGCMEncrypt(privateKeyStr, derivedKey);
369
+ const keyData = {
370
+ encrypted: true,
371
+ publicKey: publicKeyStr,
372
+ privateKeyEncrypted: encrypted,
373
+ iv,
374
+ salt: base64Encode(salt.buffer),
375
+ pbkdf2Iterations: initOptions.pbkdf2Iterations
376
+ };
377
+ window.localStorage.setItem(actualKeyStorageKey, JSON.stringify(keyData));
378
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.info) {
379
+ console.info("\u2705 Keys encrypted and stored securely");
380
+ }
381
+ } else {
382
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
383
+ console.warn(
384
+ "\u26A0\uFE0F SECURITY WARNING: Storing private keys without encryption! Private keys will be stored in plain text (Base64 encoded). Provide keyEncryptionPassword for secure storage."
385
+ );
386
+ }
387
+ const keyData = {
388
+ publicKey: publicKeyStr,
389
+ privateKey: await exportPrivateKey(globalKeyPair.privateKey)
390
+ };
391
+ window.localStorage.setItem(actualKeyStorageKey, JSON.stringify(keyData));
392
+ }
393
+ } catch (error) {
394
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
395
+ console.error("Failed to persist keys");
396
+ }
397
+ }
398
+ }
399
+ } catch (error) {
400
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
401
+ console.error("Failed to generate storage keys");
402
+ }
403
+ throw error;
404
+ }
405
+ }
406
+ if (initOptions.enableHMAC && !globalHMACKey) {
407
+ globalHMACKey = await generateHMACKey();
408
+ }
409
+ }
208
410
  function setStorageKeyPair(keyPair) {
209
411
  globalKeyPair = keyPair;
412
+ keyPairInitialized = true;
210
413
  }
211
414
  function getStorageKeyPair() {
212
415
  return globalKeyPair;
213
416
  }
214
- async function encryptValue(value, publicKey) {
215
- return rsaEncrypt(value, publicKey);
417
+ function clearPersistedKeys() {
418
+ if (typeof window !== "undefined" && window.localStorage && actualKeyStorageKey) {
419
+ try {
420
+ window.localStorage.removeItem(actualKeyStorageKey);
421
+ actualKeyStorageKey = null;
422
+ keyPairInitialized = false;
423
+ globalKeyPair = null;
424
+ globalHMACKey = null;
425
+ keyUsageCount = 0;
426
+ } catch (error) {
427
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
428
+ console.error("Failed to clear persisted keys");
429
+ }
430
+ }
431
+ }
432
+ }
433
+ function getKeyUsageCount() {
434
+ return keyUsageCount;
435
+ }
436
+ function resetKeyUsageCount() {
437
+ keyUsageCount = 0;
216
438
  }
217
- async function decryptValue(encryptedValue, privateKey) {
439
+ async function ensureKeyPair() {
440
+ if (globalKeyPair) {
441
+ keyUsageCount++;
442
+ return;
443
+ }
444
+ if (!initOptions.autoGenerateKeys) {
445
+ return;
446
+ }
447
+ if (initializationPromise) {
448
+ await initializationPromise;
449
+ if (globalKeyPair) {
450
+ keyUsageCount++;
451
+ }
452
+ return;
453
+ }
454
+ initializationPromise = initializeStorageKeys();
218
455
  try {
219
- return await rsaDecrypt(encryptedValue, privateKey);
456
+ await initializationPromise;
457
+ } finally {
458
+ initializationPromise = null;
459
+ }
460
+ if (globalKeyPair) {
461
+ keyUsageCount++;
462
+ }
463
+ }
464
+ function safeParseJSON(jsonStr, expectedType) {
465
+ try {
466
+ const parsed = JSON.parse(jsonStr);
467
+ if (expectedType === "object" && (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))) {
468
+ throw new Error("Expected object but got different type");
469
+ }
470
+ if (expectedType === "array" && !Array.isArray(parsed)) {
471
+ throw new Error("Expected array but got different type");
472
+ }
473
+ return parsed;
474
+ } catch (error) {
475
+ if (error instanceof SyntaxError) {
476
+ throw new Error(`Invalid JSON format: ${error.message}`);
477
+ }
478
+ throw error;
479
+ }
480
+ }
481
+ function validateTimestamp(timestamp, maxClockSkew = 5 * 60 * 1e3) {
482
+ if (!initOptions.enableTimestampValidation || !timestamp) {
483
+ return true;
484
+ }
485
+ if (initOptions.timestampMaxAge === 0) {
486
+ return true;
487
+ }
488
+ const now = Date.now();
489
+ const age = now - timestamp;
490
+ const maxAge = initOptions.timestampMaxAge || 7 * 24 * 60 * 60 * 1e3;
491
+ if (age < -maxClockSkew) {
492
+ return false;
493
+ }
494
+ return age >= -maxClockSkew && age <= maxAge;
495
+ }
496
+ async function encryptValue(value, publicKey, hmacKey) {
497
+ const encryptedData = await rsaEncrypt(value, publicKey);
498
+ if (hmacKey) {
499
+ const hmac = await computeHMAC(encryptedData, hmacKey);
500
+ const item = {
501
+ data: encryptedData,
502
+ hmac,
503
+ encrypted: true,
504
+ timestamp: Date.now()
505
+ };
506
+ return JSON.stringify(item);
507
+ }
508
+ return encryptedData;
509
+ }
510
+ async function handleDecryptError(error, encryptedStr, key) {
511
+ if (error instanceof Error && error.message.includes("HMAC verification failed")) {
512
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
513
+ console.error(
514
+ "\u26A0\uFE0F SECURITY ALERT: Data integrity check failed! Data may have been tampered with."
515
+ );
516
+ }
517
+ throw error;
518
+ }
519
+ if (error instanceof Error && error.message.includes("Data timestamp validation failed")) {
520
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
521
+ console.warn("\u26A0\uFE0F SECURITY WARNING: Data timestamp validation failed");
522
+ }
523
+ throw error;
524
+ }
525
+ try {
526
+ const decryptedStr = base64Decode(encryptedStr);
527
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
528
+ console.warn(
529
+ `\u26A0\uFE0F SECURITY WARNING: Reading unencrypted data for key "${key}". This may be a security risk if sensitive data was stored without encryption.`
530
+ );
531
+ }
532
+ return decryptedStr;
220
533
  } catch {
221
- try {
222
- JSON.parse(encryptedValue);
223
- return encryptedValue;
224
- } catch {
225
- throw new Error("Failed to decrypt storage value");
534
+ throw error;
535
+ }
536
+ }
537
+ function handleNoKeyDecode(encryptedStr, key) {
538
+ try {
539
+ const decryptedStr = base64Decode(encryptedStr);
540
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
541
+ console.warn(
542
+ `\u26A0\uFE0F SECURITY WARNING: Reading unencrypted data for key "${key}" without encryption keys.`
543
+ );
544
+ }
545
+ return decryptedStr;
546
+ } catch (error) {
547
+ throw new Error(`Failed to decode storage value for key "${key}"`);
548
+ }
549
+ }
550
+ async function decryptValue(encryptedValue, privateKey, hmacKey) {
551
+ try {
552
+ const item = JSON.parse(encryptedValue);
553
+ if (item.encrypted && item.data && item.hmac) {
554
+ if (hmacKey) {
555
+ const isValid = await verifyHMAC(item.data, item.hmac, hmacKey);
556
+ if (!isValid) {
557
+ throw new Error("HMAC verification failed: data may have been tampered with");
558
+ }
559
+ }
560
+ if (item.timestamp && !validateTimestamp(item.timestamp)) {
561
+ throw new Error("Data timestamp validation failed: data may be expired or replayed");
562
+ }
563
+ return await rsaDecrypt(item.data, privateKey);
564
+ }
565
+ return await rsaDecrypt(encryptedValue, privateKey);
566
+ } catch (error) {
567
+ if (error instanceof Error && error.message.includes("HMAC verification failed")) {
568
+ throw error;
226
569
  }
570
+ throw new Error("Failed to decrypt storage value: invalid format or corrupted data");
227
571
  }
228
572
  }
229
573
  var localStorage = {
@@ -245,17 +589,24 @@ var localStorage = {
245
589
  };
246
590
  try {
247
591
  const jsonStr = JSON.stringify(item);
592
+ await ensureKeyPair();
248
593
  const keyToUse = publicKey || globalKeyPair?.publicKey;
249
594
  if (keyToUse) {
250
- const encrypted = await encryptValue(jsonStr, keyToUse);
595
+ const encrypted = await encryptValue(jsonStr, keyToUse, globalHMACKey);
251
596
  window.localStorage.setItem(key, encrypted);
252
597
  } else {
253
- const { base64Encode: base64Encode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
254
- const encoded = base64Encode2(jsonStr);
598
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
599
+ console.warn(
600
+ `\u26A0\uFE0F SECURITY WARNING: Storing data without encryption for key "${key}". Data is only Base64 encoded, not encrypted!`
601
+ );
602
+ }
603
+ const encoded = base64Encode(jsonStr);
255
604
  window.localStorage.setItem(key, encoded);
256
605
  }
257
606
  } catch (error) {
258
- console.error("localStorage.set error:", error);
607
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
608
+ console.error("localStorage.set error:", error);
609
+ }
259
610
  throw error;
260
611
  }
261
612
  },
@@ -273,34 +624,36 @@ var localStorage = {
273
624
  try {
274
625
  const encryptedStr = window.localStorage.getItem(key);
275
626
  if (!encryptedStr) return defaultValue;
627
+ await ensureKeyPair();
276
628
  let decryptedStr;
277
629
  const keyToUse = privateKey || globalKeyPair?.privateKey;
278
630
  if (keyToUse) {
279
631
  try {
280
- decryptedStr = await decryptValue(encryptedStr, keyToUse);
281
- } catch {
282
- const { base64Decode: base64Decode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
632
+ decryptedStr = await decryptValue(encryptedStr, keyToUse, globalHMACKey);
633
+ } catch (error) {
283
634
  try {
284
- decryptedStr = base64Decode2(encryptedStr);
635
+ decryptedStr = await handleDecryptError(error, encryptedStr, key);
285
636
  } catch {
286
637
  return defaultValue;
287
638
  }
288
639
  }
289
640
  } else {
290
- const { base64Decode: base64Decode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
291
641
  try {
292
- decryptedStr = base64Decode2(encryptedStr);
642
+ decryptedStr = handleNoKeyDecode(encryptedStr, key);
293
643
  } catch {
294
644
  return defaultValue;
295
645
  }
296
646
  }
297
- const item = JSON.parse(decryptedStr);
647
+ const item = safeParseJSON(decryptedStr, "object");
298
648
  if (item.expiry && Date.now() > item.expiry) {
299
649
  window.localStorage.removeItem(key);
300
650
  return defaultValue;
301
651
  }
302
652
  return item.value;
303
- } catch {
653
+ } catch (error) {
654
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
655
+ console.warn(`Failed to parse storage item for key "${key}"`);
656
+ }
304
657
  return defaultValue;
305
658
  }
306
659
  },
@@ -313,7 +666,9 @@ var localStorage = {
313
666
  try {
314
667
  window.localStorage.removeItem(key);
315
668
  } catch (error) {
316
- console.error("localStorage.remove error:", error);
669
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
670
+ console.error("localStorage.remove error");
671
+ }
317
672
  }
318
673
  },
319
674
  /**
@@ -324,7 +679,9 @@ var localStorage = {
324
679
  try {
325
680
  window.localStorage.clear();
326
681
  } catch (error) {
327
- console.error("localStorage.clear error:", error);
682
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
683
+ console.error("localStorage.clear error");
684
+ }
328
685
  }
329
686
  },
330
687
  /**
@@ -340,7 +697,9 @@ var localStorage = {
340
697
  if (key) keys.push(key);
341
698
  }
342
699
  } catch (error) {
343
- console.error("localStorage.keys error:", error);
700
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
701
+ console.error("localStorage.keys error");
702
+ }
344
703
  }
345
704
  return keys;
346
705
  }
@@ -360,17 +719,24 @@ var sessionStorage = {
360
719
  const { publicKey } = options;
361
720
  try {
362
721
  const jsonStr = JSON.stringify(value);
722
+ await ensureKeyPair();
363
723
  const keyToUse = publicKey || globalKeyPair?.publicKey;
364
724
  if (keyToUse) {
365
- const encrypted = await encryptValue(jsonStr, keyToUse);
725
+ const encrypted = await encryptValue(jsonStr, keyToUse, globalHMACKey);
366
726
  window.sessionStorage.setItem(key, encrypted);
367
727
  } else {
368
- const { base64Encode: base64Encode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
369
- const encoded = base64Encode2(jsonStr);
728
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
729
+ console.warn(
730
+ `\u26A0\uFE0F SECURITY WARNING: Storing data without encryption for key "${key}". Data is only Base64 encoded, not encrypted!`
731
+ );
732
+ }
733
+ const encoded = base64Encode(jsonStr);
370
734
  window.sessionStorage.setItem(key, encoded);
371
735
  }
372
736
  } catch (error) {
373
- console.error("sessionStorage.set error:", error);
737
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
738
+ console.error("sessionStorage.set error:", error);
739
+ }
374
740
  throw error;
375
741
  }
376
742
  },
@@ -388,28 +754,27 @@ var sessionStorage = {
388
754
  try {
389
755
  const encryptedStr = window.sessionStorage.getItem(key);
390
756
  if (!encryptedStr) return defaultValue;
757
+ await ensureKeyPair();
391
758
  let decryptedStr;
392
759
  const keyToUse = privateKey || globalKeyPair?.privateKey;
393
760
  if (keyToUse) {
394
761
  try {
395
- decryptedStr = await decryptValue(encryptedStr, keyToUse);
396
- } catch {
397
- const { base64Decode: base64Decode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
762
+ decryptedStr = await decryptValue(encryptedStr, keyToUse, globalHMACKey);
763
+ } catch (error) {
398
764
  try {
399
- decryptedStr = base64Decode2(encryptedStr);
765
+ decryptedStr = await handleDecryptError(error, encryptedStr, key);
400
766
  } catch {
401
767
  return defaultValue;
402
768
  }
403
769
  }
404
770
  } else {
405
- const { base64Decode: base64Decode2 } = await Promise.resolve().then(() => (init_crypto(), crypto_exports));
406
771
  try {
407
- decryptedStr = base64Decode2(encryptedStr);
772
+ decryptedStr = handleNoKeyDecode(encryptedStr, key);
408
773
  } catch {
409
774
  return defaultValue;
410
775
  }
411
776
  }
412
- return JSON.parse(decryptedStr);
777
+ return safeParseJSON(decryptedStr);
413
778
  } catch {
414
779
  return defaultValue;
415
780
  }
@@ -423,7 +788,9 @@ var sessionStorage = {
423
788
  try {
424
789
  window.sessionStorage.removeItem(key);
425
790
  } catch (error) {
426
- console.error("sessionStorage.remove error:", error);
791
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
792
+ console.error("sessionStorage.remove error");
793
+ }
427
794
  }
428
795
  },
429
796
  /**
@@ -434,7 +801,9 @@ var sessionStorage = {
434
801
  try {
435
802
  window.sessionStorage.clear();
436
803
  } catch (error) {
437
- console.error("sessionStorage.clear error:", error);
804
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.error) {
805
+ console.error("sessionStorage.clear error");
806
+ }
438
807
  }
439
808
  }
440
809
  };
@@ -469,10 +838,15 @@ var cookie = {
469
838
  if (typeof document === "undefined") return void 0;
470
839
  const name = encodeURIComponent(key);
471
840
  const cookies = document.cookie.split(";");
472
- for (const cookie2 of cookies) {
473
- const [cookieKey, cookieValue] = cookie2.trim().split("=");
841
+ for (const cookieStr of cookies) {
842
+ const trimmed = cookieStr.trim();
843
+ const eqIndex = trimmed.indexOf("=");
844
+ if (eqIndex === -1) continue;
845
+ const cookieKey = trimmed.substring(0, eqIndex).trim();
846
+ const cookieValue = trimmed.substring(eqIndex + 1).trim();
474
847
  if (cookieKey === name) {
475
- return decodeURIComponent(cookieValue);
848
+ const decoded = decodeURIComponent(cookieValue);
849
+ return decoded === "" ? void 0 : decoded;
476
850
  }
477
851
  }
478
852
  return void 0;
@@ -496,15 +870,24 @@ var cookie = {
496
870
  if (typeof document === "undefined") return {};
497
871
  const cookies = {};
498
872
  document.cookie.split(";").forEach((cookieStr) => {
499
- const [key, value] = cookieStr.trim().split("=");
873
+ const trimmed = cookieStr.trim();
874
+ if (!trimmed) return;
875
+ const eqIndex = trimmed.indexOf("=");
876
+ if (eqIndex === -1) return;
877
+ const key = trimmed.substring(0, eqIndex).trim();
878
+ const value = trimmed.substring(eqIndex + 1).trim();
500
879
  if (key && value) {
501
- cookies[decodeURIComponent(key)] = decodeURIComponent(value);
880
+ const decodedKey = decodeURIComponent(key);
881
+ const decodedValue = decodeURIComponent(value);
882
+ if (decodedValue !== "") {
883
+ cookies[decodedKey] = decodedValue;
884
+ }
502
885
  }
503
886
  });
504
887
  return cookies;
505
888
  }
506
889
  };
507
- var storage = {
890
+ var secureStorage = {
508
891
  /**
509
892
  * 设置值(优先使用localStorage,失败则使用sessionStorage)
510
893
  * @param key - 键
@@ -519,7 +902,9 @@ var storage = {
519
902
  try {
520
903
  await sessionStorage.set(key, value, { publicKey: options.publicKey });
521
904
  } catch {
522
- console.warn("Both localStorage and sessionStorage are not available");
905
+ if (!initOptions.isProduction && typeof console !== "undefined" && console.warn) {
906
+ console.warn("Both localStorage and sessionStorage are not available");
907
+ }
523
908
  }
524
909
  }
525
910
  },
@@ -549,12 +934,32 @@ var storage = {
549
934
  clear() {
550
935
  localStorage.clear();
551
936
  sessionStorage.clear();
937
+ },
938
+ /**
939
+ * 获取所有键名
940
+ * @returns 键名数组
941
+ */
942
+ keys() {
943
+ const localKeys = localStorage.keys();
944
+ const sessionKeys = [];
945
+ if (typeof window !== "undefined" && window.sessionStorage) {
946
+ try {
947
+ for (let i = 0; i < window.sessionStorage.length; i++) {
948
+ const key = window.sessionStorage.key(i);
949
+ if (key) sessionKeys.push(key);
950
+ }
951
+ } catch (error) {
952
+ }
953
+ }
954
+ return Array.from(/* @__PURE__ */ new Set([...localKeys, ...sessionKeys]));
552
955
  }
553
956
  };
554
957
 
958
+ exports.clearPersistedKeys = clearPersistedKeys;
555
959
  exports.cookie = cookie;
960
+ exports.getKeyUsageCount = getKeyUsageCount;
556
961
  exports.getStorageKeyPair = getStorageKeyPair;
557
- exports.localStorage = localStorage;
558
- exports.sessionStorage = sessionStorage;
962
+ exports.initializeStorageKeys = initializeStorageKeys;
963
+ exports.resetKeyUsageCount = resetKeyUsageCount;
964
+ exports.secureStorage = secureStorage;
559
965
  exports.setStorageKeyPair = setStorageKeyPair;
560
- exports.storage = storage;