import { AES, enc } from 'crypto-js'; import { ENC_STORAGE_KEY } from './encryption-key'; /** * Interface defining encryption service methods. */ interface IEncryptionUtils { encrypt(data: string): string; decrypt(encryptedData: string): string; } export class EncryptionUtils implements IEncryptionUtils { private readonly _key: string; /** * @param key - Encryption key used for encrypting and decrypting data. * If not provided, defaults to ENC_STORAGE_KEY. */ constructor(key: string = ENC_STORAGE_KEY) { if (!key) { throw new Error('[EncryptionUtils] Encryption key is missing/empty.'); } this._key = key; } /** * Encrypts the given data string. * Returns an empty string '' if input data is empty. */ public encrypt(data: string): string { if (!data) { return ''; } return AES.encrypt(data, this._key).toString(); } /** * Decrypts the given encrypted data string. * Returns an empty string '' if input is empty or decryption fails. */ public decrypt(encryptedData: string): string { if (!encryptedData) { return ''; } try { const bytes = AES.decrypt(encryptedData, this._key); const originalText = bytes.toString(enc.Utf8); // If decryption yields an empty string, consider it a failure if (!originalText) { return ''; } return originalText; } catch (error) { console.error('[EncryptionUtils] Decryption failed:', error); return ''; } } /** * Get the singleton instance of EncryptionUtils. * Uses the default ENC_STORAGE_KEY. * @return EncryptionUtils instance */ private static instance: EncryptionUtils; public static getInstance(): EncryptionUtils { if (!EncryptionUtils.instance) { EncryptionUtils.instance = new EncryptionUtils(); } return EncryptionUtils.instance; } }