@bantis/local-cipher 2.1.0 → 2.3.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 +85 -2
- package/dist/angular/SecureStorageService.d.ts +1 -1
- package/dist/angular/StorageService.d.ts +22 -0
- package/dist/angular.d.ts +1 -0
- package/dist/angular.esm.js +539 -53
- package/dist/angular.esm.js.map +1 -1
- package/dist/angular.js +550 -52
- package/dist/angular.js.map +1 -1
- package/dist/core/EncryptionHelper.d.ts +1 -0
- package/dist/core/NamespacedStorage.d.ts +3 -0
- package/dist/core/SecureCookie.d.ts +41 -0
- package/dist/core/SecureStorage.d.ts +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.esm.js +493 -51
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +503 -50
- package/dist/index.js.map +1 -1
- package/dist/managers/CookieManager.d.ts +17 -0
- package/dist/managers/PlainCookie.d.ts +14 -0
- package/dist/managers/PlainStorage.d.ts +13 -0
- package/dist/managers/StorageManager.d.ts +17 -0
- package/dist/managers/index.d.ts +17 -0
- package/dist/react/hooks.d.ts +20 -2
- package/dist/react.d.ts +1 -1
- package/dist/react.esm.js +518 -59
- package/dist/react.esm.js.map +1 -1
- package/dist/react.js +529 -59
- package/dist/react.js.map +1 -1
- package/dist/types/index.d.ts +36 -0
- package/package.json +8 -4
package/dist/angular.js
CHANGED
|
@@ -23,6 +23,9 @@ const DEFAULT_CONFIG = {
|
|
|
23
23
|
compressionThreshold: 1024,
|
|
24
24
|
autoCleanup: true,
|
|
25
25
|
cleanupInterval: 60000,
|
|
26
|
+
enableCache: true,
|
|
27
|
+
verifyIntegrityOnRead: false,
|
|
28
|
+
storageEngine: typeof window !== 'undefined' ? window.localStorage : {},
|
|
26
29
|
},
|
|
27
30
|
debug: {
|
|
28
31
|
enabled: false,
|
|
@@ -50,6 +53,8 @@ class EncryptionHelper {
|
|
|
50
53
|
this.baseKey = '';
|
|
51
54
|
this.baseKeyPromise = null;
|
|
52
55
|
this.keyVersion = 1;
|
|
56
|
+
// Cache para optimización de rendimiento
|
|
57
|
+
this.keyNameCache = new Map();
|
|
53
58
|
this.config = { ...DEFAULT_CONFIG.encryption, ...config };
|
|
54
59
|
// Load key version from storage
|
|
55
60
|
const storedVersion = localStorage.getItem(EncryptionHelper.KEY_VERSION_KEY);
|
|
@@ -112,7 +117,7 @@ class EncryptionHelper {
|
|
|
112
117
|
// Derivar la clave AES-GCM
|
|
113
118
|
return crypto.subtle.deriveKey({
|
|
114
119
|
name: 'PBKDF2',
|
|
115
|
-
salt,
|
|
120
|
+
salt: salt,
|
|
116
121
|
iterations: this.config.iterations,
|
|
117
122
|
hash: EncryptionHelper.HASH_ALGORITHM,
|
|
118
123
|
}, keyMaterial, {
|
|
@@ -219,10 +224,16 @@ class EncryptionHelper {
|
|
|
219
224
|
* @returns Nombre encriptado con prefijo __enc_
|
|
220
225
|
*/
|
|
221
226
|
async encryptKey(keyName) {
|
|
227
|
+
// Optimización: devolver desde cache si existe
|
|
228
|
+
if (this.keyNameCache.has(keyName)) {
|
|
229
|
+
return this.keyNameCache.get(keyName);
|
|
230
|
+
}
|
|
222
231
|
const baseKey = await this.generateBaseKey();
|
|
223
232
|
const combined = keyName + baseKey;
|
|
224
233
|
const hash = await this.hashString(combined);
|
|
225
|
-
|
|
234
|
+
const encryptedKey = `__enc_${hash.substring(0, 16)}`;
|
|
235
|
+
this.keyNameCache.set(keyName, encryptedKey);
|
|
236
|
+
return encryptedKey;
|
|
226
237
|
}
|
|
227
238
|
/**
|
|
228
239
|
* Limpia todos los datos encriptados del localStorage
|
|
@@ -240,10 +251,11 @@ class EncryptionHelper {
|
|
|
240
251
|
keysToRemove.forEach(key => localStorage.removeItem(key));
|
|
241
252
|
// Eliminar salt
|
|
242
253
|
localStorage.removeItem(EncryptionHelper.SALT_STORAGE_KEY);
|
|
243
|
-
// Resetear clave en memoria
|
|
254
|
+
// Resetear clave en memoria y cache
|
|
244
255
|
this.key = null;
|
|
245
256
|
this.baseKey = '';
|
|
246
257
|
this.baseKeyPromise = null;
|
|
258
|
+
this.keyNameCache.clear();
|
|
247
259
|
}
|
|
248
260
|
/**
|
|
249
261
|
* Verifica si el navegador soporta Web Crypto API
|
|
@@ -394,7 +406,7 @@ class Logger {
|
|
|
394
406
|
return false;
|
|
395
407
|
return Logger.LOG_LEVELS[level] <= Logger.LOG_LEVELS[this.logLevel];
|
|
396
408
|
}
|
|
397
|
-
formatMessage(level, message
|
|
409
|
+
formatMessage(level, message) {
|
|
398
410
|
const timestamp = new Date().toISOString();
|
|
399
411
|
return `[${this.prefix}] [${level.toUpperCase()}] ${timestamp} - ${message}`;
|
|
400
412
|
}
|
|
@@ -547,17 +559,37 @@ class NamespacedStorage {
|
|
|
547
559
|
this.storage = storage;
|
|
548
560
|
this.prefix = `__ns_${namespace}__`;
|
|
549
561
|
}
|
|
562
|
+
async getIndex() {
|
|
563
|
+
const indexValue = await this.storage.getItem(`${this.prefix}__index__`);
|
|
564
|
+
return indexValue ? JSON.parse(indexValue) : [];
|
|
565
|
+
}
|
|
566
|
+
async saveToIndex(key) {
|
|
567
|
+
const index = await this.getIndex();
|
|
568
|
+
if (!index.includes(key)) {
|
|
569
|
+
index.push(key);
|
|
570
|
+
await this.storage.setItem(`${this.prefix}__index__`, JSON.stringify(index));
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
async removeFromIndex(key) {
|
|
574
|
+
const index = await this.getIndex();
|
|
575
|
+
const newIndex = index.filter(k => k !== key);
|
|
576
|
+
if (newIndex.length !== index.length) {
|
|
577
|
+
await this.storage.setItem(`${this.prefix}__index__`, JSON.stringify(newIndex));
|
|
578
|
+
}
|
|
579
|
+
}
|
|
550
580
|
/**
|
|
551
581
|
* Set item in this namespace
|
|
552
582
|
*/
|
|
553
583
|
async setItem(key, value) {
|
|
554
|
-
|
|
584
|
+
await this.storage.setItem(`${this.prefix}${key}`, value);
|
|
585
|
+
await this.saveToIndex(key);
|
|
555
586
|
}
|
|
556
587
|
/**
|
|
557
588
|
* Set item with expiry in this namespace
|
|
558
589
|
*/
|
|
559
590
|
async setItemWithExpiry(key, value, options) {
|
|
560
|
-
|
|
591
|
+
await this.storage.setItemWithExpiry(`${this.prefix}${key}`, value, options);
|
|
592
|
+
await this.saveToIndex(key);
|
|
561
593
|
}
|
|
562
594
|
/**
|
|
563
595
|
* Get item from this namespace
|
|
@@ -569,7 +601,8 @@ class NamespacedStorage {
|
|
|
569
601
|
* Remove item from this namespace
|
|
570
602
|
*/
|
|
571
603
|
async removeItem(key) {
|
|
572
|
-
|
|
604
|
+
await this.storage.removeItem(`${this.prefix}${key}`);
|
|
605
|
+
await this.removeFromIndex(key);
|
|
573
606
|
}
|
|
574
607
|
/**
|
|
575
608
|
* Check if item exists in this namespace
|
|
@@ -581,29 +614,17 @@ class NamespacedStorage {
|
|
|
581
614
|
* Clear all items in this namespace
|
|
582
615
|
*/
|
|
583
616
|
async clearNamespace() {
|
|
584
|
-
const keysToRemove =
|
|
585
|
-
for (let i = 0; i < localStorage.length; i++) {
|
|
586
|
-
const key = localStorage.key(i);
|
|
587
|
-
if (key && key.includes(this.prefix)) {
|
|
588
|
-
keysToRemove.push(key.replace(this.prefix, ''));
|
|
589
|
-
}
|
|
590
|
-
}
|
|
617
|
+
const keysToRemove = await this.getIndex();
|
|
591
618
|
for (const key of keysToRemove) {
|
|
592
|
-
await this.removeItem(key);
|
|
619
|
+
await this.storage.removeItem(`${this.prefix}${key}`);
|
|
593
620
|
}
|
|
621
|
+
await this.storage.removeItem(`${this.prefix}__index__`);
|
|
594
622
|
}
|
|
595
623
|
/**
|
|
596
624
|
* Get all keys in this namespace
|
|
597
625
|
*/
|
|
598
626
|
async keys() {
|
|
599
|
-
|
|
600
|
-
for (let i = 0; i < localStorage.length; i++) {
|
|
601
|
-
const key = localStorage.key(i);
|
|
602
|
-
if (key && key.includes(this.prefix)) {
|
|
603
|
-
keys.push(key.replace(this.prefix, ''));
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
return keys;
|
|
627
|
+
return this.getIndex();
|
|
607
628
|
}
|
|
608
629
|
}
|
|
609
630
|
|
|
@@ -626,7 +647,6 @@ async function compress(data) {
|
|
|
626
647
|
return encoder.encode(data);
|
|
627
648
|
}
|
|
628
649
|
try {
|
|
629
|
-
const encoder = new TextEncoder();
|
|
630
650
|
const stream = new Blob([data]).stream();
|
|
631
651
|
const compressedStream = stream.pipeThrough(new CompressionStream('gzip'));
|
|
632
652
|
const compressedBlob = await new Response(compressedStream).blob();
|
|
@@ -675,6 +695,7 @@ function shouldCompress(data, threshold = 1024) {
|
|
|
675
695
|
class SecureStorage {
|
|
676
696
|
constructor(config) {
|
|
677
697
|
this.cleanupInterval = null;
|
|
698
|
+
this.memoryCache = new Map();
|
|
678
699
|
// Merge config with defaults
|
|
679
700
|
this.config = {
|
|
680
701
|
encryption: { ...DEFAULT_CONFIG.encryption, ...config?.encryption },
|
|
@@ -756,8 +777,12 @@ class SecureStorage {
|
|
|
756
777
|
const encryptedKey = await this.encryptionHelper.encryptKey(key);
|
|
757
778
|
// Encrypt the value
|
|
758
779
|
const encryptedValue = await this.encryptionHelper.encrypt(serialized);
|
|
759
|
-
// Store in
|
|
760
|
-
|
|
780
|
+
// Store in storage
|
|
781
|
+
this.config.storage.storageEngine.setItem(encryptedKey, encryptedValue);
|
|
782
|
+
// Update cache
|
|
783
|
+
if (this.config.storage.enableCache) {
|
|
784
|
+
this.memoryCache.set(key, { value });
|
|
785
|
+
}
|
|
761
786
|
this.logger.verbose(`Stored key: ${key}, compressed: ${compressed}, size: ${encryptedValue.length}`);
|
|
762
787
|
this.eventEmitter.emit('encrypted', { key, metadata: { compressed, size: encryptedValue.length } });
|
|
763
788
|
this.logger.timeEnd(`setItem:${key}`);
|
|
@@ -765,7 +790,7 @@ class SecureStorage {
|
|
|
765
790
|
catch (error) {
|
|
766
791
|
this.logger.error(`Error al guardar dato encriptado para ${key}:`, error);
|
|
767
792
|
this.eventEmitter.emit('error', { key, error: error });
|
|
768
|
-
|
|
793
|
+
this.config.storage.storageEngine.setItem(key, value);
|
|
769
794
|
}
|
|
770
795
|
}
|
|
771
796
|
/**
|
|
@@ -818,8 +843,12 @@ class SecureStorage {
|
|
|
818
843
|
const encryptedKey = await this.encryptionHelper.encryptKey(key);
|
|
819
844
|
// Encrypt the value
|
|
820
845
|
const encryptedValue = await this.encryptionHelper.encrypt(serialized);
|
|
821
|
-
// Store in
|
|
822
|
-
|
|
846
|
+
// Store in storage
|
|
847
|
+
this.config.storage.storageEngine.setItem(encryptedKey, encryptedValue);
|
|
848
|
+
// Update cache
|
|
849
|
+
if (this.config.storage.enableCache) {
|
|
850
|
+
this.memoryCache.set(key, { value, expiresAt });
|
|
851
|
+
}
|
|
823
852
|
this.logger.verbose(`Stored key with expiry: ${key}, expiresAt: ${expiresAt}`);
|
|
824
853
|
this.eventEmitter.emit('encrypted', { key, metadata: { compressed, expiresAt } });
|
|
825
854
|
this.logger.timeEnd(`setItemWithExpiry:${key}`);
|
|
@@ -836,16 +865,31 @@ class SecureStorage {
|
|
|
836
865
|
async getItem(key) {
|
|
837
866
|
this.logger.time(`getItem:${key}`);
|
|
838
867
|
if (!EncryptionHelper.isSupported()) {
|
|
839
|
-
return
|
|
868
|
+
return this.config.storage.storageEngine.getItem(key);
|
|
840
869
|
}
|
|
841
870
|
try {
|
|
871
|
+
// Check memory cache first
|
|
872
|
+
if (this.config.storage.enableCache && this.memoryCache.has(key)) {
|
|
873
|
+
const cached = this.memoryCache.get(key);
|
|
874
|
+
if (cached.expiresAt && cached.expiresAt < Date.now()) {
|
|
875
|
+
this.logger.info(`Key expired in cache: ${key}`);
|
|
876
|
+
await this.removeItem(key);
|
|
877
|
+
this.eventEmitter.emit('expired', { key });
|
|
878
|
+
this.logger.timeEnd(`getItem:${key}`);
|
|
879
|
+
return null;
|
|
880
|
+
}
|
|
881
|
+
this.logger.debug(`Retrieved from cache: ${key}`);
|
|
882
|
+
this.eventEmitter.emit('decrypted', { key });
|
|
883
|
+
this.logger.timeEnd(`getItem:${key}`);
|
|
884
|
+
return cached.value;
|
|
885
|
+
}
|
|
842
886
|
// Encrypt the key
|
|
843
887
|
const encryptedKey = await this.encryptionHelper.encryptKey(key);
|
|
844
888
|
// Get encrypted value
|
|
845
|
-
let encryptedValue =
|
|
889
|
+
let encryptedValue = this.config.storage.storageEngine.getItem(encryptedKey);
|
|
846
890
|
// Backward compatibility: try with plain key
|
|
847
891
|
if (!encryptedValue) {
|
|
848
|
-
encryptedValue =
|
|
892
|
+
encryptedValue = this.config.storage.storageEngine.getItem(key);
|
|
849
893
|
if (!encryptedValue) {
|
|
850
894
|
this.logger.timeEnd(`getItem:${key}`);
|
|
851
895
|
return null;
|
|
@@ -881,8 +925,8 @@ class SecureStorage {
|
|
|
881
925
|
this.logger.timeEnd(`getItem:${key}`);
|
|
882
926
|
return null;
|
|
883
927
|
}
|
|
884
|
-
// Verify integrity if checksum exists
|
|
885
|
-
if (storedValue.checksum) {
|
|
928
|
+
// Verify integrity if checksum exists and configured
|
|
929
|
+
if (storedValue.checksum && this.config.storage.verifyIntegrityOnRead) {
|
|
886
930
|
const calculatedChecksum = await this.calculateChecksum(storedValue.value);
|
|
887
931
|
if (calculatedChecksum !== storedValue.checksum) {
|
|
888
932
|
this.logger.warn(`Integrity check failed for key: ${key}`);
|
|
@@ -900,6 +944,9 @@ class SecureStorage {
|
|
|
900
944
|
finalValue = await decompress(new Uint8Array(compressedData));
|
|
901
945
|
this.eventEmitter.emit('decompressed', { key });
|
|
902
946
|
}
|
|
947
|
+
if (this.config.storage.enableCache) {
|
|
948
|
+
this.memoryCache.set(key, { value: finalValue, expiresAt: storedValue.expiresAt });
|
|
949
|
+
}
|
|
903
950
|
this.eventEmitter.emit('decrypted', { key });
|
|
904
951
|
this.logger.timeEnd(`getItem:${key}`);
|
|
905
952
|
return finalValue;
|
|
@@ -908,7 +955,7 @@ class SecureStorage {
|
|
|
908
955
|
this.logger.error(`Error al recuperar dato encriptado para ${key}:`, error);
|
|
909
956
|
this.eventEmitter.emit('error', { key, error: error });
|
|
910
957
|
// Fallback: try plain key
|
|
911
|
-
const fallback =
|
|
958
|
+
const fallback = this.config.storage.storageEngine.getItem(key);
|
|
912
959
|
this.logger.timeEnd(`getItem:${key}`);
|
|
913
960
|
return fallback;
|
|
914
961
|
}
|
|
@@ -918,19 +965,20 @@ class SecureStorage {
|
|
|
918
965
|
*/
|
|
919
966
|
async removeItem(key) {
|
|
920
967
|
if (!EncryptionHelper.isSupported()) {
|
|
921
|
-
|
|
968
|
+
this.config.storage.storageEngine.removeItem(key);
|
|
922
969
|
return;
|
|
923
970
|
}
|
|
924
971
|
try {
|
|
925
972
|
const encryptedKey = await this.encryptionHelper.encryptKey(key);
|
|
926
|
-
|
|
927
|
-
|
|
973
|
+
this.config.storage.storageEngine.removeItem(encryptedKey);
|
|
974
|
+
this.config.storage.storageEngine.removeItem(key); // Remove both versions
|
|
975
|
+
this.memoryCache.delete(key);
|
|
928
976
|
this.eventEmitter.emit('deleted', { key });
|
|
929
977
|
this.logger.info(`Removed key: ${key}`);
|
|
930
978
|
}
|
|
931
979
|
catch (error) {
|
|
932
980
|
this.logger.error(`Error al eliminar dato para ${key}:`, error);
|
|
933
|
-
|
|
981
|
+
this.config.storage.storageEngine.removeItem(key);
|
|
934
982
|
}
|
|
935
983
|
}
|
|
936
984
|
/**
|
|
@@ -945,6 +993,7 @@ class SecureStorage {
|
|
|
945
993
|
*/
|
|
946
994
|
clear() {
|
|
947
995
|
this.encryptionHelper.clearEncryptedData();
|
|
996
|
+
this.memoryCache.clear();
|
|
948
997
|
this.eventEmitter.emit('cleared', {});
|
|
949
998
|
this.logger.info('All encrypted data cleared');
|
|
950
999
|
}
|
|
@@ -955,21 +1004,28 @@ class SecureStorage {
|
|
|
955
1004
|
this.logger.info('Starting cleanup of expired items...');
|
|
956
1005
|
let cleanedCount = 0;
|
|
957
1006
|
const keysToCheck = [];
|
|
958
|
-
for (let i = 0; i <
|
|
959
|
-
const key =
|
|
1007
|
+
for (let i = 0; i < this.config.storage.storageEngine.length; i++) {
|
|
1008
|
+
const key = this.config.storage.storageEngine.key(i);
|
|
960
1009
|
if (key && key.startsWith('__enc_')) {
|
|
961
1010
|
keysToCheck.push(key);
|
|
962
1011
|
}
|
|
963
1012
|
}
|
|
964
1013
|
for (const encryptedKey of keysToCheck) {
|
|
965
1014
|
try {
|
|
966
|
-
const encryptedValue =
|
|
1015
|
+
const encryptedValue = this.config.storage.storageEngine.getItem(encryptedKey);
|
|
967
1016
|
if (!encryptedValue)
|
|
968
1017
|
continue;
|
|
969
1018
|
const decrypted = await this.encryptionHelper.decrypt(encryptedValue);
|
|
970
1019
|
const storedValue = JSON.parse(decrypted);
|
|
971
1020
|
if (storedValue.expiresAt && storedValue.expiresAt < Date.now()) {
|
|
972
|
-
|
|
1021
|
+
this.config.storage.storageEngine.removeItem(encryptedKey);
|
|
1022
|
+
// Encontrar la clave original en el cache y eliminarla
|
|
1023
|
+
for (const [cacheKey] of Array.from(this.memoryCache.entries())) {
|
|
1024
|
+
this.encryptionHelper.encryptKey(cacheKey).then(enc => {
|
|
1025
|
+
if (enc === encryptedKey)
|
|
1026
|
+
this.memoryCache.delete(cacheKey);
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
973
1029
|
cleanedCount++;
|
|
974
1030
|
this.eventEmitter.emit('expired', { key: encryptedKey });
|
|
975
1031
|
}
|
|
@@ -987,7 +1043,7 @@ class SecureStorage {
|
|
|
987
1043
|
async verifyIntegrity(key) {
|
|
988
1044
|
try {
|
|
989
1045
|
const encryptedKey = await this.encryptionHelper.encryptKey(key);
|
|
990
|
-
const encryptedValue =
|
|
1046
|
+
const encryptedValue = this.config.storage.storageEngine.getItem(encryptedKey);
|
|
991
1047
|
if (!encryptedValue)
|
|
992
1048
|
return false;
|
|
993
1049
|
const decrypted = await this.encryptionHelper.decrypt(encryptedValue);
|
|
@@ -1010,7 +1066,7 @@ class SecureStorage {
|
|
|
1010
1066
|
async getIntegrityInfo(key) {
|
|
1011
1067
|
try {
|
|
1012
1068
|
const encryptedKey = await this.encryptionHelper.encryptKey(key);
|
|
1013
|
-
const encryptedValue =
|
|
1069
|
+
const encryptedValue = this.config.storage.storageEngine.getItem(encryptedKey);
|
|
1014
1070
|
if (!encryptedValue)
|
|
1015
1071
|
return null;
|
|
1016
1072
|
const decrypted = await this.encryptionHelper.decrypt(encryptedValue);
|
|
@@ -1093,7 +1149,7 @@ class SecureStorage {
|
|
|
1093
1149
|
this.logger.info(`Iniciando migración de ${keys.length} claves...`);
|
|
1094
1150
|
for (const key of keys) {
|
|
1095
1151
|
try {
|
|
1096
|
-
const value =
|
|
1152
|
+
const value = this.config.storage.storageEngine.getItem(key);
|
|
1097
1153
|
if (value === null)
|
|
1098
1154
|
continue;
|
|
1099
1155
|
// Try to decrypt to check if already encrypted
|
|
@@ -1106,7 +1162,7 @@ class SecureStorage {
|
|
|
1106
1162
|
// Not encrypted, proceed with migration
|
|
1107
1163
|
}
|
|
1108
1164
|
await this.setItem(key, value);
|
|
1109
|
-
|
|
1165
|
+
this.config.storage.storageEngine.removeItem(key);
|
|
1110
1166
|
this.logger.info(`✓ ${key} migrado exitosamente`);
|
|
1111
1167
|
}
|
|
1112
1168
|
catch (error) {
|
|
@@ -1120,8 +1176,8 @@ class SecureStorage {
|
|
|
1120
1176
|
*/
|
|
1121
1177
|
getDebugInfo() {
|
|
1122
1178
|
const allKeys = [];
|
|
1123
|
-
for (let i = 0; i <
|
|
1124
|
-
const key =
|
|
1179
|
+
for (let i = 0; i < this.config.storage.storageEngine.length; i++) {
|
|
1180
|
+
const key = this.config.storage.storageEngine.key(i);
|
|
1125
1181
|
if (key)
|
|
1126
1182
|
allKeys.push(key);
|
|
1127
1183
|
}
|
|
@@ -1155,10 +1211,199 @@ class SecureStorage {
|
|
|
1155
1211
|
}
|
|
1156
1212
|
this.removeAllListeners();
|
|
1157
1213
|
this.logger.info('SecureStorage destroyed');
|
|
1214
|
+
SecureStorage.instance = null;
|
|
1158
1215
|
}
|
|
1159
1216
|
}
|
|
1160
1217
|
SecureStorage.instance = null;
|
|
1161
1218
|
|
|
1219
|
+
/**
|
|
1220
|
+
* SecureCookie - API de alto nivel para almacenamiento en cookies cifradas
|
|
1221
|
+
* Soporta opciones de cookies incluyendo domininios/subdominios y compresión.
|
|
1222
|
+
*/
|
|
1223
|
+
class SecureCookie {
|
|
1224
|
+
constructor(config) {
|
|
1225
|
+
this.config = {
|
|
1226
|
+
encryption: { ...DEFAULT_CONFIG.encryption, ...config?.encryption },
|
|
1227
|
+
cookieOptions: { path: '/', ...config?.cookieOptions },
|
|
1228
|
+
compression: config?.compression ?? true,
|
|
1229
|
+
debug: { ...DEFAULT_CONFIG.debug, ...config?.debug }
|
|
1230
|
+
};
|
|
1231
|
+
this.logger = new Logger(this.config.debug);
|
|
1232
|
+
this.encryptionHelper = new EncryptionHelper(this.config.encryption);
|
|
1233
|
+
this.logger.info('SecureCookie initialized', this.config);
|
|
1234
|
+
}
|
|
1235
|
+
/**
|
|
1236
|
+
* Obtiene la instancia singleton de SecureCookie
|
|
1237
|
+
*/
|
|
1238
|
+
static getInstance(config) {
|
|
1239
|
+
if (!SecureCookie.instance) {
|
|
1240
|
+
SecureCookie.instance = new SecureCookie(config);
|
|
1241
|
+
}
|
|
1242
|
+
return SecureCookie.instance;
|
|
1243
|
+
}
|
|
1244
|
+
/**
|
|
1245
|
+
* Serializa las opciones de cookie en un string
|
|
1246
|
+
*/
|
|
1247
|
+
serializeOptions(options) {
|
|
1248
|
+
let cookieString = '';
|
|
1249
|
+
if (options.expires) {
|
|
1250
|
+
cookieString += `; expires=${options.expires.toUTCString()}`;
|
|
1251
|
+
}
|
|
1252
|
+
if (options.maxAge) {
|
|
1253
|
+
cookieString += `; max-age=${options.maxAge}`;
|
|
1254
|
+
}
|
|
1255
|
+
if (options.domain) {
|
|
1256
|
+
cookieString += `; domain=${options.domain}`;
|
|
1257
|
+
}
|
|
1258
|
+
if (options.path) {
|
|
1259
|
+
cookieString += `; path=${options.path}`;
|
|
1260
|
+
}
|
|
1261
|
+
if (options.secure) {
|
|
1262
|
+
cookieString += `; secure`;
|
|
1263
|
+
}
|
|
1264
|
+
if (options.sameSite) {
|
|
1265
|
+
cookieString += `; samesite=${options.sameSite}`;
|
|
1266
|
+
}
|
|
1267
|
+
return cookieString;
|
|
1268
|
+
}
|
|
1269
|
+
/**
|
|
1270
|
+
* Guarda un valor encriptado en una cookie
|
|
1271
|
+
*/
|
|
1272
|
+
async set(name, value, options) {
|
|
1273
|
+
this.logger.time(`cookie:set:${name}`);
|
|
1274
|
+
if (!EncryptionHelper.isSupported()) {
|
|
1275
|
+
this.logger.warn('Web Crypto API no soportada, guardando cookie sin cifrar');
|
|
1276
|
+
const mergedOptions = { ...this.config.cookieOptions, ...options };
|
|
1277
|
+
document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}${this.serializeOptions(mergedOptions)}`;
|
|
1278
|
+
return;
|
|
1279
|
+
}
|
|
1280
|
+
try {
|
|
1281
|
+
// Check compression (aggressively compress cookies to save space since max is ~4KB)
|
|
1282
|
+
const shouldCompressData = this.config.compression && shouldCompress(value, 200);
|
|
1283
|
+
let processedValue = value;
|
|
1284
|
+
let metadataPrefix = 'P_'; // P_ = Plain
|
|
1285
|
+
if (shouldCompressData) {
|
|
1286
|
+
this.logger.debug(`Compressing cookie value for: ${name}`);
|
|
1287
|
+
const compressedData = await compress(value);
|
|
1288
|
+
processedValue = this.encryptionHelper['arrayBufferToBase64'](compressedData.buffer);
|
|
1289
|
+
metadataPrefix = 'C_'; // C_ = Compressed
|
|
1290
|
+
}
|
|
1291
|
+
// Encrypt key name
|
|
1292
|
+
const encryptedKey = await this.encryptionHelper.encryptKey(name);
|
|
1293
|
+
// Serialize and Encrypt Value
|
|
1294
|
+
// Adding metadata prefix to avoid bloating value with massive StoredValue JSON headers
|
|
1295
|
+
const encryptedData = await this.encryptionHelper.encrypt(processedValue);
|
|
1296
|
+
const finalValue = metadataPrefix + encryptedData;
|
|
1297
|
+
// Prepare Cookie string
|
|
1298
|
+
const mergedOptions = { ...this.config.cookieOptions, ...options };
|
|
1299
|
+
const cookieOptionsStr = this.serializeOptions(mergedOptions);
|
|
1300
|
+
const cookieString = `${encodeURIComponent(encryptedKey)}=${encodeURIComponent(finalValue)}${cookieOptionsStr}`;
|
|
1301
|
+
// Verificación de tamaño de cookie
|
|
1302
|
+
if (cookieString.length > 4096) {
|
|
1303
|
+
this.logger.warn(`Cookie '${name}' es muy grande (${cookieString.length} bytes). Puede ser rechazada por el navegador.`);
|
|
1304
|
+
}
|
|
1305
|
+
document.cookie = cookieString;
|
|
1306
|
+
this.logger.verbose(`Stored cookie: ${name}`);
|
|
1307
|
+
this.logger.timeEnd(`cookie:set:${name}`);
|
|
1308
|
+
}
|
|
1309
|
+
catch (error) {
|
|
1310
|
+
this.logger.error(`Error al guardar cookie encriptada para ${name}:`, error);
|
|
1311
|
+
// Fallback sin cifrar como último recurso
|
|
1312
|
+
const mergedOptions = { ...this.config.cookieOptions, ...options };
|
|
1313
|
+
document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}${this.serializeOptions(mergedOptions)}`;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
/**
|
|
1317
|
+
* Pide una cookie por nombre
|
|
1318
|
+
* Retorna el string o null si no existe
|
|
1319
|
+
*/
|
|
1320
|
+
getRawCookie(name) {
|
|
1321
|
+
const nameEQ = encodeURIComponent(name) + '=';
|
|
1322
|
+
const ca = document.cookie.split(';');
|
|
1323
|
+
for (let i = 0; i < ca.length; i++) {
|
|
1324
|
+
let c = ca[i];
|
|
1325
|
+
while (c.charAt(0) === ' ')
|
|
1326
|
+
c = c.substring(1, c.length);
|
|
1327
|
+
if (c.indexOf(nameEQ) === 0)
|
|
1328
|
+
return decodeURIComponent(c.substring(nameEQ.length, c.length));
|
|
1329
|
+
}
|
|
1330
|
+
return null;
|
|
1331
|
+
}
|
|
1332
|
+
/**
|
|
1333
|
+
* Recupera y desencripta un valor de cookie
|
|
1334
|
+
*/
|
|
1335
|
+
async get(name) {
|
|
1336
|
+
this.logger.time(`cookie:get:${name}`);
|
|
1337
|
+
if (!EncryptionHelper.isSupported()) {
|
|
1338
|
+
return this.getRawCookie(name);
|
|
1339
|
+
}
|
|
1340
|
+
try {
|
|
1341
|
+
// Find encrypted key
|
|
1342
|
+
const encryptedKey = await this.encryptionHelper.encryptKey(name);
|
|
1343
|
+
let rawValue = this.getRawCookie(encryptedKey);
|
|
1344
|
+
if (!rawValue) {
|
|
1345
|
+
// Backward compatibility just in case fallback was used
|
|
1346
|
+
rawValue = this.getRawCookie(name);
|
|
1347
|
+
if (!rawValue) {
|
|
1348
|
+
this.logger.timeEnd(`cookie:get:${name}`);
|
|
1349
|
+
return null;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
// Check if it has our metadata prefixes
|
|
1353
|
+
if (!rawValue.startsWith('P_') && !rawValue.startsWith('C_')) {
|
|
1354
|
+
// Podría ser un fallback plano
|
|
1355
|
+
this.logger.timeEnd(`cookie:get:${name}`);
|
|
1356
|
+
return rawValue; // Asumimos que es plano
|
|
1357
|
+
}
|
|
1358
|
+
const isCompressed = rawValue.startsWith('C_');
|
|
1359
|
+
const encryptedData = rawValue.substring(2);
|
|
1360
|
+
// Decrypt
|
|
1361
|
+
const decryptedString = await this.encryptionHelper.decrypt(encryptedData);
|
|
1362
|
+
// Decompress if needed
|
|
1363
|
+
let finalValue = decryptedString;
|
|
1364
|
+
if (isCompressed) {
|
|
1365
|
+
const compressedBuffer = this.encryptionHelper['base64ToArrayBuffer'](decryptedString);
|
|
1366
|
+
finalValue = await decompress(new Uint8Array(compressedBuffer));
|
|
1367
|
+
}
|
|
1368
|
+
this.logger.timeEnd(`cookie:get:${name}`);
|
|
1369
|
+
return finalValue;
|
|
1370
|
+
}
|
|
1371
|
+
catch (error) {
|
|
1372
|
+
this.logger.error(`Error al recuperar cookie encriptada para ${name}:`, error);
|
|
1373
|
+
// Fallback
|
|
1374
|
+
return this.getRawCookie(name);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Elimina una cookie
|
|
1379
|
+
*/
|
|
1380
|
+
async remove(name, options) {
|
|
1381
|
+
const mergedOptions = { ...this.config.cookieOptions, ...options };
|
|
1382
|
+
// Expirar la cookie configurándole una fecha del pasado
|
|
1383
|
+
const expireOptions = {
|
|
1384
|
+
...mergedOptions,
|
|
1385
|
+
expires: new Date(0),
|
|
1386
|
+
maxAge: 0
|
|
1387
|
+
};
|
|
1388
|
+
if (!EncryptionHelper.isSupported()) {
|
|
1389
|
+
document.cookie = `${encodeURIComponent(name)}=${this.serializeOptions(expireOptions)}`;
|
|
1390
|
+
return;
|
|
1391
|
+
}
|
|
1392
|
+
const encryptedKey = await this.encryptionHelper.encryptKey(name);
|
|
1393
|
+
// Remove encrypted cookie
|
|
1394
|
+
document.cookie = `${encodeURIComponent(encryptedKey)}=${this.serializeOptions(expireOptions)}`;
|
|
1395
|
+
// Also remove plain version just in case
|
|
1396
|
+
document.cookie = `${encodeURIComponent(name)}=${this.serializeOptions(expireOptions)}`;
|
|
1397
|
+
}
|
|
1398
|
+
/**
|
|
1399
|
+
* Limpia la instancia actual (útil para testing o refresco)
|
|
1400
|
+
*/
|
|
1401
|
+
destroy() {
|
|
1402
|
+
SecureCookie.instance = null;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
SecureCookie.instance = null;
|
|
1406
|
+
|
|
1162
1407
|
const secureStorage$1 = SecureStorage.getInstance();
|
|
1163
1408
|
/**
|
|
1164
1409
|
* Función de debug para verificar el estado del sistema de encriptación
|
|
@@ -1211,6 +1456,202 @@ async function forceMigration(customKeys) {
|
|
|
1211
1456
|
await debugEncryptionState();
|
|
1212
1457
|
}
|
|
1213
1458
|
|
|
1459
|
+
/**
|
|
1460
|
+
* PlainStorage - Una interfaz consistente con SecureStorage pero sin cifrado.
|
|
1461
|
+
* Envuelve localStorage o sessionStorage con serialización JSON.
|
|
1462
|
+
*/
|
|
1463
|
+
class PlainStorage {
|
|
1464
|
+
constructor(storageEngine = typeof window !== 'undefined' ? window.localStorage : {}) {
|
|
1465
|
+
this.storage = storageEngine;
|
|
1466
|
+
this.logger = new Logger({ prefix: 'PlainStorage' });
|
|
1467
|
+
}
|
|
1468
|
+
async set(key, value) {
|
|
1469
|
+
try {
|
|
1470
|
+
const serialized = typeof value === 'string' ? value : JSON.stringify(value);
|
|
1471
|
+
this.storage.setItem(key, serialized);
|
|
1472
|
+
}
|
|
1473
|
+
catch (error) {
|
|
1474
|
+
this.logger.error(`Error saving unencrypted item ${key}:`, error);
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
async get(key) {
|
|
1478
|
+
try {
|
|
1479
|
+
const value = this.storage.getItem(key);
|
|
1480
|
+
if (value === null)
|
|
1481
|
+
return null;
|
|
1482
|
+
try {
|
|
1483
|
+
return JSON.parse(value);
|
|
1484
|
+
}
|
|
1485
|
+
catch {
|
|
1486
|
+
return value; // Fallback for plain strings
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
catch (error) {
|
|
1490
|
+
this.logger.error(`Error reading unencrypted item ${key}:`, error);
|
|
1491
|
+
return null;
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
async remove(key) {
|
|
1495
|
+
this.storage.removeItem(key);
|
|
1496
|
+
}
|
|
1497
|
+
clear() {
|
|
1498
|
+
this.storage.clear();
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
/**
|
|
1503
|
+
* Crea una instancia de almacenamiento encriptado.
|
|
1504
|
+
* @param engine 'localStorage' o 'sessionStorage'
|
|
1505
|
+
* @param secretKey Llave secreta opcional para derivación de claves
|
|
1506
|
+
* @param config Configuración adicional opcional
|
|
1507
|
+
* @returns Instancia de SecureStorage
|
|
1508
|
+
*/
|
|
1509
|
+
function createEncryptedStorage(engine = 'localStorage', secretKey, config) {
|
|
1510
|
+
const defaultEngine = typeof window !== 'undefined'
|
|
1511
|
+
? (engine === 'sessionStorage' ? window.sessionStorage : window.localStorage)
|
|
1512
|
+
: {};
|
|
1513
|
+
const mergedConfig = {
|
|
1514
|
+
...config,
|
|
1515
|
+
encryption: {
|
|
1516
|
+
...config?.encryption,
|
|
1517
|
+
...(secretKey ? { appIdentifier: secretKey } : {})
|
|
1518
|
+
},
|
|
1519
|
+
storage: {
|
|
1520
|
+
...config?.storage,
|
|
1521
|
+
storageEngine: defaultEngine
|
|
1522
|
+
}
|
|
1523
|
+
};
|
|
1524
|
+
return SecureStorage.getInstance(mergedConfig);
|
|
1525
|
+
}
|
|
1526
|
+
/**
|
|
1527
|
+
* Crea una instancia de almacenamiento plano (sin cifrar).
|
|
1528
|
+
* @param engine 'localStorage' o 'sessionStorage'
|
|
1529
|
+
* @returns Instancia de PlainStorage
|
|
1530
|
+
*/
|
|
1531
|
+
function createPlainStorage(engine = 'localStorage') {
|
|
1532
|
+
const defaultEngine = typeof window !== 'undefined'
|
|
1533
|
+
? (engine === 'sessionStorage' ? window.sessionStorage : window.localStorage)
|
|
1534
|
+
: {};
|
|
1535
|
+
return new PlainStorage(defaultEngine);
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
/**
|
|
1539
|
+
* PlainCookie - Una interfaz consistente con SecureCookie pero sin cifrado.
|
|
1540
|
+
*/
|
|
1541
|
+
class PlainCookie {
|
|
1542
|
+
constructor(defaultOptions) {
|
|
1543
|
+
this.logger = new Logger({ prefix: 'PlainCookie' });
|
|
1544
|
+
this.defaultOptions = { path: '/', ...defaultOptions };
|
|
1545
|
+
}
|
|
1546
|
+
serializeOptions(options) {
|
|
1547
|
+
let cookieString = '';
|
|
1548
|
+
if (options.expires)
|
|
1549
|
+
cookieString += `; expires=${options.expires.toUTCString()}`;
|
|
1550
|
+
if (options.maxAge)
|
|
1551
|
+
cookieString += `; max-age=${options.maxAge}`;
|
|
1552
|
+
if (options.domain)
|
|
1553
|
+
cookieString += `; domain=${options.domain}`;
|
|
1554
|
+
if (options.path)
|
|
1555
|
+
cookieString += `; path=${options.path}`;
|
|
1556
|
+
if (options.secure)
|
|
1557
|
+
cookieString += `; secure`;
|
|
1558
|
+
if (options.sameSite)
|
|
1559
|
+
cookieString += `; samesite=${options.sameSite}`;
|
|
1560
|
+
return cookieString;
|
|
1561
|
+
}
|
|
1562
|
+
async set(name, value, options) {
|
|
1563
|
+
try {
|
|
1564
|
+
const serialized = typeof value === 'string' ? value : JSON.stringify(value);
|
|
1565
|
+
const mergedOptions = { ...this.defaultOptions, ...options };
|
|
1566
|
+
document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(serialized)}${this.serializeOptions(mergedOptions)}`;
|
|
1567
|
+
}
|
|
1568
|
+
catch (error) {
|
|
1569
|
+
this.logger.error(`Error saving unencrypted cookie ${name}:`, error);
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
async get(name) {
|
|
1573
|
+
try {
|
|
1574
|
+
const nameEQ = encodeURIComponent(name) + '=';
|
|
1575
|
+
const ca = document.cookie.split(';');
|
|
1576
|
+
for (let i = 0; i < ca.length; i++) {
|
|
1577
|
+
let c = ca[i];
|
|
1578
|
+
while (c.charAt(0) === ' ')
|
|
1579
|
+
c = c.substring(1, c.length);
|
|
1580
|
+
if (c.indexOf(nameEQ) === 0) {
|
|
1581
|
+
const decoded = decodeURIComponent(c.substring(nameEQ.length, c.length));
|
|
1582
|
+
try {
|
|
1583
|
+
return JSON.parse(decoded);
|
|
1584
|
+
}
|
|
1585
|
+
catch {
|
|
1586
|
+
return decoded;
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
return null;
|
|
1591
|
+
}
|
|
1592
|
+
catch (error) {
|
|
1593
|
+
this.logger.error(`Error reading unencrypted cookie ${name}:`, error);
|
|
1594
|
+
return null;
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
async remove(name, options) {
|
|
1598
|
+
const mergedOptions = { ...this.defaultOptions, ...options };
|
|
1599
|
+
document.cookie = `${encodeURIComponent(name)}=${this.serializeOptions({ ...mergedOptions, expires: new Date(0), maxAge: 0 })}`;
|
|
1600
|
+
}
|
|
1601
|
+
clearAll() {
|
|
1602
|
+
const cookies = document.cookie.split(';');
|
|
1603
|
+
for (let i = 0; i < cookies.length; i++) {
|
|
1604
|
+
const cookie = cookies[i];
|
|
1605
|
+
const eqPos = cookie.indexOf('=');
|
|
1606
|
+
const name = eqPos > -1 ? cookie.substring(0, eqPos).trim() : cookie.trim();
|
|
1607
|
+
this.remove(decodeURIComponent(name));
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
/**
|
|
1613
|
+
* Crea una instancia de manejador de cookies encriptadas.
|
|
1614
|
+
* @param secretKey Llave secreta opcional para derivación de claves
|
|
1615
|
+
* @param domain Dominio opcional (incluir punto inicial para subdominios ej. '.dominio.com')
|
|
1616
|
+
* @param config Configuración adicional opcional
|
|
1617
|
+
* @returns Instancia de SecureCookie
|
|
1618
|
+
*/
|
|
1619
|
+
function createEncryptedCookieManager(secretKey, domain, config) {
|
|
1620
|
+
const mergedConfig = {
|
|
1621
|
+
...config,
|
|
1622
|
+
encryption: {
|
|
1623
|
+
...config?.encryption,
|
|
1624
|
+
...(secretKey ? { appIdentifier: secretKey } : {})
|
|
1625
|
+
},
|
|
1626
|
+
cookieOptions: {
|
|
1627
|
+
...config?.cookieOptions,
|
|
1628
|
+
...(domain ? { domain } : {})
|
|
1629
|
+
}
|
|
1630
|
+
};
|
|
1631
|
+
return SecureCookie.getInstance(mergedConfig);
|
|
1632
|
+
}
|
|
1633
|
+
/**
|
|
1634
|
+
* Crea una instancia de manejador de cookies plano (sin cifrar).
|
|
1635
|
+
* @param defaultOptions Opciones por defecto para las cookies (ej. domain)
|
|
1636
|
+
* @returns Instancia de PlainCookie
|
|
1637
|
+
*/
|
|
1638
|
+
function createPlainCookieManager(defaultOptions) {
|
|
1639
|
+
return new PlainCookie(defaultOptions);
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
/**
|
|
1643
|
+
* Instancia predeterminada de almacenamiento local (sin cifrar).
|
|
1644
|
+
*/
|
|
1645
|
+
const localStore = createPlainStorage('localStorage');
|
|
1646
|
+
/**
|
|
1647
|
+
* Instancia predeterminada de almacenamiento de sesión (sin cifrar).
|
|
1648
|
+
*/
|
|
1649
|
+
const sessionStore = createPlainStorage('sessionStorage');
|
|
1650
|
+
/**
|
|
1651
|
+
* Instancia predeterminada de gestor de cookies (sin cifrar).
|
|
1652
|
+
*/
|
|
1653
|
+
const cookies = createPlainCookieManager();
|
|
1654
|
+
|
|
1214
1655
|
/**
|
|
1215
1656
|
* @bantis/local-cipher - Core Module
|
|
1216
1657
|
* Framework-agnostic client-side encryption for browser storage
|
|
@@ -1220,8 +1661,9 @@ async function forceMigration(customKeys) {
|
|
|
1220
1661
|
*/
|
|
1221
1662
|
// Core classes
|
|
1222
1663
|
const secureStorage = SecureStorage.getInstance();
|
|
1664
|
+
const secureCookie = SecureCookie.getInstance();
|
|
1223
1665
|
// Version
|
|
1224
|
-
const VERSION = '2.
|
|
1666
|
+
const VERSION = '2.2.0';
|
|
1225
1667
|
|
|
1226
1668
|
/******************************************************************************
|
|
1227
1669
|
Copyright (c) Microsoft Corporation.
|
|
@@ -1476,7 +1918,7 @@ let SecureStorageService = (() => {
|
|
|
1476
1918
|
* @returns Observable con el objeto parseado o null
|
|
1477
1919
|
*/
|
|
1478
1920
|
getObject(key) {
|
|
1479
|
-
return this.getItem(key).pipe(operators.map(value => value ? JSON.parse(value) : null), operators.catchError(() => rxjs.from([null])));
|
|
1921
|
+
return this.getItem(key).pipe(operators.map((value) => value ? JSON.parse(value) : null), operators.catchError(() => rxjs.from([null])));
|
|
1480
1922
|
}
|
|
1481
1923
|
/**
|
|
1482
1924
|
* Registra un listener para un tipo de evento específico
|
|
@@ -1500,7 +1942,7 @@ let SecureStorageService = (() => {
|
|
|
1500
1942
|
* @returns Observable con eventos del tipo especificado
|
|
1501
1943
|
*/
|
|
1502
1944
|
onEvent$(eventType) {
|
|
1503
|
-
return this.events$.pipe(operators.map(event => event.type === eventType ? event : null), operators.map(event => event));
|
|
1945
|
+
return this.events$.pipe(operators.map((event) => event.type === eventType ? event : null), operators.map((event) => event));
|
|
1504
1946
|
}
|
|
1505
1947
|
};
|
|
1506
1948
|
__setFunctionName(_classThis, "SecureStorageService");
|
|
@@ -1514,6 +1956,50 @@ let SecureStorageService = (() => {
|
|
|
1514
1956
|
return _classThis;
|
|
1515
1957
|
})();
|
|
1516
1958
|
|
|
1959
|
+
let StorageService = (() => {
|
|
1960
|
+
let _classDecorators = [core.Injectable({
|
|
1961
|
+
providedIn: 'root'
|
|
1962
|
+
})];
|
|
1963
|
+
let _classDescriptor;
|
|
1964
|
+
let _classExtraInitializers = [];
|
|
1965
|
+
let _classThis;
|
|
1966
|
+
_classThis = class {
|
|
1967
|
+
constructor() {
|
|
1968
|
+
/** Acceso directo a localStorage sin cifrar */
|
|
1969
|
+
this.local = localStore;
|
|
1970
|
+
/** Acceso directo a sessionStorage sin cifrar */
|
|
1971
|
+
this.session = sessionStore;
|
|
1972
|
+
/** Acceso directo a cookies sin cifrar */
|
|
1973
|
+
this.cookies = cookies;
|
|
1974
|
+
}
|
|
1975
|
+
/**
|
|
1976
|
+
* Crea una instancia de almacenamiento sincronizado y cifrado
|
|
1977
|
+
* @param engine local o session storage
|
|
1978
|
+
* @param secretKey Llave de cifrado
|
|
1979
|
+
*/
|
|
1980
|
+
createEncryptedStorage(engine, secretKey) {
|
|
1981
|
+
return createEncryptedStorage(engine, secretKey);
|
|
1982
|
+
}
|
|
1983
|
+
/**
|
|
1984
|
+
* Crea un gestor de cookies cifradas
|
|
1985
|
+
* @param secretKey Llave de cifrado
|
|
1986
|
+
* @param domain Configuración de subdominios
|
|
1987
|
+
*/
|
|
1988
|
+
createEncryptedCookieManager(secretKey, domain) {
|
|
1989
|
+
return createEncryptedCookieManager(secretKey, domain);
|
|
1990
|
+
}
|
|
1991
|
+
};
|
|
1992
|
+
__setFunctionName(_classThis, "StorageService");
|
|
1993
|
+
(() => {
|
|
1994
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
1995
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
1996
|
+
_classThis = _classDescriptor.value;
|
|
1997
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
1998
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
1999
|
+
})();
|
|
2000
|
+
return _classThis;
|
|
2001
|
+
})();
|
|
2002
|
+
|
|
1517
2003
|
exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
|
|
1518
2004
|
exports.EncryptionHelper = EncryptionHelper;
|
|
1519
2005
|
exports.EventEmitter = EventEmitter;
|
|
@@ -1521,15 +2007,27 @@ exports.KeyRotation = KeyRotation;
|
|
|
1521
2007
|
exports.LIBRARY_VERSION = LIBRARY_VERSION;
|
|
1522
2008
|
exports.Logger = Logger;
|
|
1523
2009
|
exports.NamespacedStorage = NamespacedStorage;
|
|
2010
|
+
exports.PlainCookie = PlainCookie;
|
|
2011
|
+
exports.PlainStorage = PlainStorage;
|
|
1524
2012
|
exports.STORAGE_VERSION = STORAGE_VERSION;
|
|
2013
|
+
exports.SecureCookie = SecureCookie;
|
|
1525
2014
|
exports.SecureStorage = SecureStorage;
|
|
1526
2015
|
exports.SecureStorageService = SecureStorageService;
|
|
2016
|
+
exports.StorageService = StorageService;
|
|
1527
2017
|
exports.VERSION = VERSION;
|
|
1528
2018
|
exports.compress = compress;
|
|
2019
|
+
exports.cookies = cookies;
|
|
2020
|
+
exports.createEncryptedCookieManager = createEncryptedCookieManager;
|
|
2021
|
+
exports.createEncryptedStorage = createEncryptedStorage;
|
|
2022
|
+
exports.createPlainCookieManager = createPlainCookieManager;
|
|
2023
|
+
exports.createPlainStorage = createPlainStorage;
|
|
1529
2024
|
exports.debugEncryptionState = debugEncryptionState;
|
|
1530
2025
|
exports.decompress = decompress;
|
|
1531
2026
|
exports.forceMigration = forceMigration;
|
|
1532
2027
|
exports.isCompressionSupported = isCompressionSupported;
|
|
2028
|
+
exports.localStore = localStore;
|
|
2029
|
+
exports.secureCookie = secureCookie;
|
|
1533
2030
|
exports.secureStorage = secureStorage;
|
|
2031
|
+
exports.sessionStore = sessionStore;
|
|
1534
2032
|
exports.shouldCompress = shouldCompress;
|
|
1535
2033
|
//# sourceMappingURL=angular.js.map
|