UNPKG

tl-shared-security

Version:

Enterprise-grade security module for frontend and backend applications with comprehensive protection against XSS, CSRF, SQL injection, and other security vulnerabilities

186 lines 6.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.secureStorage = exports.SecureStorage = void 0; class SecureStorage { constructor(options) { this.options = { prefix: 'secure_', encryptionKey: '', useSessionStorage: false, expiryInMinutes: 60, // 1 hour ...options, }; // Check if we're in a browser environment this.storage = typeof window !== 'undefined' ? (this.options.useSessionStorage ? window.sessionStorage : window.localStorage) : null; } /** * Sets an item in secure storage * @param key - Storage key * @param value - Value to store * @param customExpiry - Custom expiry time in minutes */ setItem(key, value, customExpiry) { if (!this.storage) return; try { const prefixedKey = this.getPrefixedKey(key); const expiryTime = Date.now() + ((customExpiry || this.options.expiryInMinutes) * 60 * 1000); const dataToStore = { value, expiry: expiryTime, }; const serialized = JSON.stringify(dataToStore); const encrypted = this.options.encryptionKey ? this.encrypt(serialized, this.options.encryptionKey) : serialized; this.storage.setItem(prefixedKey, encrypted); } catch (error) { console.error('Error setting secure storage item:', error); } } /** * Gets an item from secure storage * @param key - Storage key * @param defaultValue - Default value if item doesn't exist * @returns Stored value or default value */ getItem(key, defaultValue) { if (!this.storage) return defaultValue; try { const prefixedKey = this.getPrefixedKey(key); const encrypted = this.storage.getItem(prefixedKey); if (!encrypted) return defaultValue; const serialized = this.options.encryptionKey ? this.decrypt(encrypted, this.options.encryptionKey) : encrypted; const data = JSON.parse(serialized); // Check if expired if (data.expiry && data.expiry < Date.now()) { this.removeItem(key); return defaultValue; } return data.value; } catch (error) { console.error('Error getting secure storage item:', error); return defaultValue; } } /** * Removes an item from secure storage * @param key - Storage key */ removeItem(key) { if (!this.storage) return; try { const prefixedKey = this.getPrefixedKey(key); this.storage.removeItem(prefixedKey); } catch (error) { console.error('Error removing secure storage item:', error); } } /** * Clears all items from secure storage with the configured prefix */ clear() { if (!this.storage) return; try { const keysToRemove = []; for (let i = 0; i < this.storage.length; i++) { const key = this.storage.key(i); if (key && key.startsWith(this.options.prefix)) { keysToRemove.push(key); } } keysToRemove.forEach(key => this.storage?.removeItem(key)); } catch (error) { console.error('Error clearing secure storage:', error); } } /** * Gets all keys in secure storage with the configured prefix * @returns Array of keys */ getAllKeys() { if (!this.storage) return []; try { const keys = []; for (let i = 0; i < this.storage.length; i++) { const key = this.storage.key(i); if (key && key.startsWith(this.options.prefix)) { keys.push(key.slice(this.options.prefix.length)); } } return keys; } catch (error) { console.error('Error getting secure storage keys:', error); return []; } } /** * Removes expired items from secure storage */ removeExpiredItems() { if (!this.storage) return; try { const keys = this.getAllKeys(); keys.forEach(key => { this.getItem(key); // This will remove the item if expired }); } catch (error) { console.error('Error removing expired items:', error); } } getPrefixedKey(key) { return `${this.options.prefix}${key}`; } encrypt(text, key) { if (typeof window === 'undefined') return text; try { // Simple XOR encryption for browser compatibility let result = ''; for (let i = 0; i < text.length; i++) { result += String.fromCharCode(text.charCodeAt(i) ^ key.charCodeAt(i % key.length)); } return btoa(result); } catch (error) { console.error('Encryption error:', error); return text; } } decrypt(encrypted, key) { if (typeof window === 'undefined') return encrypted; try { const text = atob(encrypted); let result = ''; for (let i = 0; i < text.length; i++) { result += String.fromCharCode(text.charCodeAt(i) ^ key.charCodeAt(i % key.length)); } return result; } catch (error) { console.error('Decryption error:', error); return encrypted; } } } exports.SecureStorage = SecureStorage; // Export default instance exports.secureStorage = new SecureStorage(); //# sourceMappingURL=secure-storage.js.map