@bantis/local-cipher 1.0.1 → 2.0.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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 MTT
3
+ Copyright (c) 2026 MTT (Master Tech Team)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,253 +1,314 @@
1
1
  # @bantis/local-cipher
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@bantis/local-cipher.svg)](https://www.npmjs.com/package/@bantis/local-cipher)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@bantis/local-cipher.svg)](https://www.npmjs.com/package/@bantis/local-cipher)
4
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![GitHub](https://img.shields.io/badge/GitHub-master--tech--team-blue)](https://github.com/master-tech-team/-bantis-local-cipher)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue)](https://www.typescriptlang.org/)
6
7
 
7
- Librería de cifrado local AES-256-GCM para proteger datos sensibles en localStorage. Compatible con **Angular**, **React** y **JavaScript vanilla**.
8
+ **Client-side encryption for localStorage using AES-256-GCM**
8
9
 
9
- ## 🔐 Características
10
+ Protect sensitive data in browser storage from XSS attacks, local file access, and casual inspection. Drop-in replacement for localStorage with automatic encryption/decryption.
10
11
 
11
- - ✅ **Cifrado AES-256-GCM** - Estándar de cifrado avanzado con autenticación
12
- - ✅ **Derivación de claves PBKDF2** - 100,000 iteraciones con SHA-256
13
- - ✅ **Browser Fingerprinting** - Claves únicas por navegador
14
- - ✅ **Ofuscación de nombres** - Los nombres de las claves también se encriptan
15
- - ✅ **TypeScript** - Tipado completo
16
- - ✅ **Framework Agnostic** - Funciona con cualquier proyecto JavaScript
17
- - ✅ **Integraciones específicas** - Hooks de React y servicio de Angular
18
- - ✅ **Migración automática** - Convierte datos existentes a formato encriptado
19
- - ✅ **Fallback transparente** - Funciona en navegadores sin Web Crypto API
12
+ ## Problem
20
13
 
21
- ## 📦 Instalación
14
+ localStorage stores data in **plain text**. Anyone with access to DevTools, browser files, or malicious scripts can read:
15
+ - Authentication tokens
16
+ - User credentials
17
+ - API keys
18
+ - Personal information
19
+
20
+ ## Solution
21
+
22
+ Transparent AES-256-GCM encryption with browser fingerprinting. Data is encrypted before storage and decrypted on retrieval. Keys are derived from browser characteristics, making data unreadable outside the original browser context.
23
+
24
+ ## Quick Start
22
25
 
23
26
  ```bash
24
- npm install @mtt/local-cipher
27
+ npm install @bantis/local-cipher
25
28
  ```
26
29
 
27
- ## 🚀 Uso Rápido
30
+ ```typescript
31
+ import { SecureStorage } from '@bantis/local-cipher';
28
32
 
29
- ### JavaScript Vanilla
33
+ const storage = SecureStorage.getInstance();
30
34
 
31
- ```javascript
32
- import { secureStorage } from '@mtt/local-cipher';
35
+ // Store encrypted
36
+ await storage.setItem('token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...');
33
37
 
34
- // Guardar datos encriptados
35
- await secureStorage.setItem('accessToken', 'mi-token-secreto');
38
+ // Retrieve decrypted
39
+ const token = await storage.getItem('token');
36
40
 
37
- // Leer datos desencriptados
38
- const token = await secureStorage.getItem('accessToken');
41
+ // Works like localStorage
42
+ await storage.removeItem('token');
43
+ storage.clear();
44
+ ```
39
45
 
40
- // Eliminar datos
41
- await secureStorage.removeItem('accessToken');
46
+ **Before:**
47
+ ```
48
+ localStorage: { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }
49
+ ```
42
50
 
43
- // Limpiar todo
44
- secureStorage.clear();
51
+ **After:**
52
+ ```
53
+ localStorage: { "__enc_a7f5d8e2": "Qm9keUVuY3J5cHRlZERhdGE..." }
45
54
  ```
46
55
 
47
- ### React
56
+ ## Features
48
57
 
49
- ```jsx
50
- import { useSecureStorage } from '@mtt/local-cipher';
58
+ - ✅ **AES-256-GCM** encryption with authentication
59
+ - **PBKDF2** key derivation (100k+ iterations)
60
+ - ✅ **Browser fingerprinting** for unique keys per device
61
+ - ✅ **Key obfuscation** - even key names are encrypted
62
+ - ✅ **TTL/Expiration** - auto-delete expired data
63
+ - ✅ **Event system** - monitor storage operations
64
+ - ✅ **Compression** - automatic gzip for large values
65
+ - ✅ **Namespaces** - organize data in isolated spaces
66
+ - ✅ **Integrity checks** - SHA-256 checksums
67
+ - ✅ **TypeScript** - full type definitions
68
+ - ✅ **Framework support** - React hooks, Angular service
51
69
 
52
- function App() {
53
- const [token, setToken, loading] = useSecureStorage('accessToken', '');
54
-
55
- if (loading) return <div>Cargando...</div>;
56
-
57
- return (
58
- <div>
59
- <p>Token: {token}</p>
60
- <button onClick={() => setToken('nuevo-token')}>
61
- Actualizar Token
62
- </button>
63
- </div>
64
- );
65
- }
66
- ```
70
+ ## Use Cases
67
71
 
68
- ### Angular
72
+ ### 1. Protect Authentication Tokens
69
73
 
70
74
  ```typescript
71
- import { SecureStorageService } from '@mtt/local-cipher';
75
+ // Store JWT with 1-hour expiration
76
+ await storage.setItemWithExpiry('accessToken', jwt, {
77
+ expiresIn: 3600000
78
+ });
79
+
80
+ // Auto-cleanup expired tokens
81
+ storage.on('expired', ({ key }) => {
82
+ console.log(`Token ${key} expired, redirecting to login`);
83
+ window.location.href = '/login';
84
+ });
85
+ ```
72
86
 
73
- @Component({
74
- selector: 'app-root',
75
- template: `<div>{{ token$ | async }}</div>`
76
- })
77
- export class AppComponent {
78
- token$ = this.secureStorage.getItem('accessToken');
87
+ ### 2. Secure User Preferences
79
88
 
80
- constructor(private secureStorage: SecureStorageService) {}
89
+ ```typescript
90
+ const userStorage = storage.namespace('user');
91
+ await userStorage.setItem('theme', 'dark');
92
+ await userStorage.setItem('language', 'en');
81
93
 
82
- saveToken(token: string) {
83
- this.secureStorage.setItem('accessToken', token).subscribe();
84
- }
85
- }
94
+ // Isolated from other namespaces
95
+ const appStorage = storage.namespace('app');
86
96
  ```
87
97
 
88
- ## 📚 Documentación Completa
98
+ ### 3. Cache Sensitive API Responses
89
99
 
90
- ### API Principal
100
+ ```typescript
101
+ // Store with compression for large data
102
+ const storage = SecureStorage.getInstance({
103
+ storage: { compression: true, compressionThreshold: 512 }
104
+ });
91
105
 
92
- #### `SecureStorage`
106
+ await storage.setItem('userData', JSON.stringify(largeObject));
107
+ ```
93
108
 
94
- **`setItem(key: string, value: string): Promise<void>`**
95
- Guarda un valor encriptado en localStorage.
109
+ ## React Integration
96
110
 
97
- **`getItem(key: string): Promise<string | null>`**
98
- Recupera y desencripta un valor de localStorage.
111
+ ```tsx
112
+ import { useSecureStorage, useSecureStorageEvents } from '@bantis/local-cipher';
99
113
 
100
- **`removeItem(key: string): Promise<void>`**
101
- Elimina un valor de localStorage.
114
+ function App() {
115
+ const [token, setToken, loading] = useSecureStorage('token', '');
116
+
117
+ useSecureStorageEvents('expired', () => {
118
+ // Handle expiration
119
+ });
120
+
121
+ if (loading) return <div>Loading...</div>;
122
+
123
+ return <div>Token: {token}</div>;
124
+ }
125
+ ```
102
126
 
103
- **`hasItem(key: string): Promise<boolean>`**
104
- Verifica si existe una clave.
127
+ ## Angular Integration
105
128
 
106
- **`clear(): void`**
107
- Limpia todos los datos encriptados.
129
+ ```typescript
130
+ import { SecureStorageService } from '@bantis/local-cipher';
108
131
 
109
- **`migrateExistingData(keys: string[]): Promise<void>`**
110
- Migra datos existentes no encriptados a formato encriptado.
132
+ @Component({...})
133
+ export class AppComponent {
134
+ token$ = this.storage.getItem('token');
111
135
 
112
- ### React Hooks
136
+ constructor(private storage: SecureStorageService) {
137
+ this.storage.events$.subscribe(event => {
138
+ console.log('Storage event:', event);
139
+ });
140
+ }
141
+ }
142
+ ```
113
143
 
114
- #### `useSecureStorage<T>(key: string, initialValue: T)`
115
- Hook principal para usar SecureStorage de forma reactiva.
144
+ ## Configuration
116
145
 
117
- ```jsx
118
- const [user, setUser, loading, error] = useSecureStorage('user', null);
146
+ ```typescript
147
+ const storage = SecureStorage.getInstance({
148
+ encryption: {
149
+ iterations: 150000, // PBKDF2 iterations
150
+ keyLength: 256, // 128, 192, or 256 bits
151
+ saltLength: 16, // Salt size in bytes
152
+ ivLength: 12, // IV size in bytes
153
+ },
154
+ storage: {
155
+ compression: true, // Enable gzip compression
156
+ compressionThreshold: 1024, // Compress if > 1KB
157
+ autoCleanup: true, // Auto-delete expired items
158
+ cleanupInterval: 60000 // Cleanup every 60s
159
+ },
160
+ debug: {
161
+ enabled: false, // Enable debug logging
162
+ logLevel: 'info' // silent, error, warn, info, debug, verbose
163
+ }
164
+ });
119
165
  ```
120
166
 
121
- **Retorna:** `[value, setValue, loading, error]`
167
+ ## Security
122
168
 
123
- #### `useSecureStorageItem(key: string)`
124
- Verifica si existe una clave.
169
+ ### What This Protects Against
125
170
 
126
- ```jsx
127
- const [hasToken, loading, error] = useSecureStorageItem('accessToken');
128
- ```
171
+ ✅ **XSS attacks** - Encrypted data is useless without the browser-specific key
172
+ **Local file access** - Malware reading browser files gets encrypted data
173
+ ✅ **Casual inspection** - DevTools shows encrypted values
174
+ ✅ **Data tampering** - Integrity checks detect modifications
129
175
 
130
- **Retorna:** `[exists, loading, error]`
176
+ ### What This Does NOT Protect Against
131
177
 
132
- #### `useSecureStorageDebug()`
133
- Obtiene información de debug del sistema.
178
+ **Server-side attacks** - Encryption is client-side only
179
+ **Man-in-the-Middle** - Use HTTPS for data in transit
180
+ ❌ **Memory dumps** - Keys exist in memory during runtime
181
+ ❌ **Compromised browser** - If the browser is compromised, all bets are off
182
+ ❌ **Physical access during active session** - Data is decrypted when accessed
134
183
 
135
- ```jsx
136
- const debugInfo = useSecureStorageDebug();
137
- console.log(`Claves encriptadas: ${debugInfo.encryptedKeys.length}`);
138
- ```
184
+ ### Best Practices
139
185
 
140
- ### Angular Service
186
+ 1. **Use HTTPS** - Always transmit data over secure connections
187
+ 2. **Short TTLs** - Set expiration on sensitive data
188
+ 3. **Clear on logout** - Call `storage.clear()` when user logs out
189
+ 4. **Monitor events** - Track suspicious activity via event listeners
190
+ 5. **Rotate keys** - Periodically call `storage.rotateKeys()`
191
+ 6. **Don't store passwords** - Never store plaintext passwords, even encrypted
141
192
 
142
- #### `SecureStorageService`
193
+ ## Browser Support
143
194
 
144
- ```typescript
145
- // Inyectar el servicio
146
- constructor(private secureStorage: SecureStorageService) {}
195
+ Requires [Web Crypto API](https://caniuse.com/cryptography):
147
196
 
148
- // Guardar
149
- this.secureStorage.setItem('key', 'value').subscribe();
197
+ - Chrome 37+
198
+ - Firefox 34+
199
+ - Safari 11+
200
+ - Edge 12+
201
+ - Opera 24+
150
202
 
151
- // Leer
152
- this.secureStorage.getItem('key').subscribe(value => console.log(value));
203
+ **Fallback:** Gracefully degrades to unencrypted localStorage in unsupported browsers.
153
204
 
154
- // Guardar objetos JSON
155
- this.secureStorage.setObject('user', { id: 1, name: 'Juan' }).subscribe();
205
+ ## API Reference
156
206
 
157
- // Leer objetos JSON
158
- this.secureStorage.getObject<User>('user').subscribe(user => console.log(user));
207
+ ### Core Methods
159
208
 
160
- // Obtener debug info como Observable
161
- this.secureStorage.getDebugInfo$().subscribe(info => console.log(info));
209
+ ```typescript
210
+ setItem(key: string, value: string): Promise<void>
211
+ getItem(key: string): Promise<string | null>
212
+ removeItem(key: string): Promise<void>
213
+ hasItem(key: string): Promise<boolean>
214
+ clear(): void
162
215
  ```
163
216
 
164
- ## 🔄 Migración de Datos Existentes
217
+ ### Expiration
218
+
219
+ ```typescript
220
+ setItemWithExpiry(key: string, value: string, options: {
221
+ expiresIn?: number; // milliseconds from now
222
+ expiresAt?: Date; // absolute date
223
+ }): Promise<void>
224
+
225
+ cleanExpired(): Promise<number> // Returns count of deleted items
226
+ ```
165
227
 
166
- Si ya tienes datos en localStorage sin encriptar, puedes migrarlos fácilmente:
228
+ ### Events
167
229
 
168
- ```javascript
169
- import { secureStorage } from '@mtt/local-cipher';
230
+ ```typescript
231
+ on(event: StorageEventType, listener: EventListener): void
232
+ off(event: StorageEventType, listener: EventListener): void
233
+ once(event: StorageEventType, listener: EventListener): void
170
234
 
171
- // Migrar claves específicas
172
- await secureStorage.migrateExistingData([
173
- 'accessToken',
174
- 'refreshToken',
175
- 'user',
176
- 'sessionId'
177
- ]);
235
+ // Event types: 'encrypted', 'decrypted', 'deleted', 'cleared',
236
+ // 'expired', 'error', 'keyRotated', 'compressed'
178
237
  ```
179
238
 
180
- **Recomendación:** Ejecuta esto al iniciar tu aplicación para migrar automáticamente.
239
+ ### Namespaces
181
240
 
182
- ## 🛡️ Seguridad
241
+ ```typescript
242
+ namespace(name: string): NamespacedStorage
183
243
 
184
- ### ¿Qué protege?
244
+ const userStorage = storage.namespace('user');
245
+ await userStorage.setItem('profile', data);
246
+ await userStorage.clearNamespace();
247
+ ```
185
248
 
186
- **XSS (Cross-Site Scripting)** - Los datos están encriptados incluso si un script malicioso accede a localStorage
187
- ✅ **Lectura de archivos locales** - Malware que lee archivos del navegador no puede descifrar los datos
188
- ✅ **Ofuscación** - Los nombres de las claves también están encriptados
249
+ ### Key Rotation
189
250
 
190
- ### ¿Qué NO protege?
251
+ ```typescript
252
+ rotateKeys(): Promise<void>
253
+ exportEncryptedData(): Promise<EncryptedBackup>
254
+ importEncryptedData(backup: EncryptedBackup): Promise<void>
255
+ ```
191
256
 
192
- **Ataques del lado del servidor** - La encriptación es solo del lado del cliente
193
- ❌ **Man-in-the-Middle** - Usa HTTPS para proteger datos en tránsito
194
- ❌ **Acceso físico durante sesión activa** - Si el navegador está abierto, la clave está en memoria
257
+ ## FAQ
195
258
 
196
- ### Cómo Funciona
259
+ **Q: Is this secure enough for passwords?**
260
+ A: No. Never store passwords in localStorage, even encrypted. Use secure, httpOnly cookies or sessionStorage with server-side session management.
197
261
 
198
- 1. **Fingerprinting del navegador** - Se genera una huella digital única combinando características del navegador
199
- 2. **Derivación de clave** - Se usa PBKDF2 con 100,000 iteraciones para derivar una clave AES-256
200
- 3. **Cifrado AES-GCM** - Cada valor se encripta con un IV aleatorio único
201
- 4. **Almacenamiento** - Se guarda `IV + datos encriptados` en Base64
262
+ **Q: Can data be decrypted on another device?**
263
+ A: No. Keys are derived from browser fingerprinting. Data encrypted on Chrome/Windows cannot be decrypted on Firefox/Mac.
202
264
 
203
- **Ejemplo de localStorage:**
265
+ **Q: What happens if Web Crypto API is unavailable?**
266
+ A: The library falls back to unencrypted localStorage with a console warning. Check `EncryptionHelper.isSupported()` to detect support.
204
267
 
205
- ```
206
- Antes:
207
- accessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
208
- user: '{"id":1,"name":"Juan"}'
268
+ **Q: Does this protect against XSS?**
269
+ A: Partially. It makes stolen data harder to use, but XSS can still intercept data when it's decrypted in memory. Use CSP headers and sanitize inputs.
209
270
 
210
- Después:
211
- __enc_a7f5d8e2c1b4: "Qm9keUVuY3J5cHRlZERhdGE..."
212
- __enc_9c3e7b1a5f8d: "QW5vdGhlckVuY3J5cHRlZA..."
213
- __app_salt: "cmFuZG9tU2FsdEhlcmU="
214
- ```
271
+ **Q: How is this different from sessionStorage?**
272
+ A: sessionStorage is cleared on tab close. This provides persistent, encrypted storage across sessions.
215
273
 
216
- ## 🧪 Utilidades de Debug
274
+ **Q: Can I use this in Node.js?**
275
+ A: No. This library requires browser APIs (Web Crypto, localStorage). For Node.js, use native `crypto` module.
217
276
 
218
- ```javascript
219
- import { debugEncryptionState, testEncryption, forceMigration } from '@mtt/local-cipher';
277
+ **Q: What's the performance impact?**
278
+ A: Encryption adds ~2-5ms per operation. Compression adds ~5-10ms for large values. Negligible for most use cases.
220
279
 
221
- // Ver estado del sistema
222
- await debugEncryptionState();
280
+ ## Migration from v1
223
281
 
224
- // Probar encriptación
225
- await testEncryption();
282
+ v1 data is automatically migrated to v2 format on first read. No action required.
226
283
 
227
- // Forzar migración
228
- await forceMigration(['accessToken', 'refreshToken']);
284
+ ```typescript
285
+ // v1 and v2 are API-compatible
286
+ const storage = SecureStorage.getInstance(); // Works with both
229
287
  ```
230
288
 
231
- ## 🌐 Compatibilidad
289
+ ## Examples
232
290
 
233
- Requiere navegadores con soporte para **Web Crypto API**:
291
+ See [/examples](./examples) directory for:
292
+ - Basic usage
293
+ - React integration
294
+ - Angular integration
295
+ - Advanced features (TTL, events, namespaces)
234
296
 
235
- - ✅ Chrome 37+
236
- - ✅ Firefox 34+
237
- - ✅ Safari 11+
238
- - ✅ Edge 12+
239
- - ✅ Opera 24+
297
+ ## Contributing
240
298
 
241
- **Nota:** En navegadores sin soporte, la librería hace fallback automático a localStorage normal.
299
+ Contributions welcome! Please read [CONTRIBUTING.md](./CONTRIBUTING.md) first.
242
300
 
243
- ## 📄 Licencia
301
+ ## Security Issues
244
302
 
245
- MIT © MTT
303
+ Report security vulnerabilities to [security@example.com](mailto:security@example.com). See [SECURITY.md](./SECURITY.md) for details.
246
304
 
247
- ## 🤝 Contribuir
305
+ ## License
248
306
 
249
- Las contribuciones son bienvenidas. Por favor abre un issue o pull request en GitHub.
307
+ MIT © MTT - See [LICENSE](./LICENSE) for details.
250
308
 
251
- ## 📞 Soporte
309
+ ## Links
252
310
 
253
- Si encuentras algún problema o tienes preguntas, abre un issue en GitHub.
311
+ - [npm package](https://www.npmjs.com/package/@bantis/local-cipher)
312
+ - [GitHub repository](https://github.com/master-tech-team/-bantis-local-cipher)
313
+ - [Changelog](./CHANGELOG.md)
314
+ - [Security Policy](./SECURITY.md)