import CryptoJS from 'crypto-js'; import { APP_CONFIG } from '@/config'; interface StorageEnvelope { value: T; expiresAt: number; } const AES_KEY = CryptoJS.enc.Hex.parse(CryptoJS.SHA256(APP_CONFIG.STORAGE_ENCRYPTION_KEY).toString()); const AES_IV = CryptoJS.enc.Hex.parse(CryptoJS.MD5(APP_CONFIG.STORAGE_ENCRYPTION_KEY).toString()); const encrypt = (value: unknown) => { const payload = CryptoJS.enc.Utf8.parse(JSON.stringify(value)); return CryptoJS.AES.encrypt(payload, AES_KEY, { iv: AES_IV, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }).toString(); }; const decrypt = (value: string): T | null => { try { const decrypted = CryptoJS.AES.decrypt(value, AES_KEY, { iv: AES_IV, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }).toString(CryptoJS.enc.Utf8); if (decrypted) { return JSON.parse(decrypted) as T; } // Backward compatibility for old passphrase-based ciphertexts. const legacy = CryptoJS.AES.decrypt(value, APP_CONFIG.STORAGE_ENCRYPTION_KEY).toString(CryptoJS.enc.Utf8); return legacy ? JSON.parse(legacy) as T : null; } catch (error) { return null; } }; export const encryptedStorage = { set(key: string, value: T, expiresInSeconds = 0) { const envelope: StorageEnvelope = { value, expiresAt: expiresInSeconds > 0 ? Date.now() + expiresInSeconds * 1000 : 0 }; uni.setStorageSync(key, encrypt(envelope)); }, get(key: string): T | null { const encryptedValue = uni.getStorageSync(key); if (typeof encryptedValue !== 'string' || !encryptedValue) return null; const envelope = decrypt>(encryptedValue); if (!envelope || typeof envelope !== 'object' || !('value' in envelope)) { uni.removeStorageSync(key); return null; } if (envelope.expiresAt > 0 && envelope.expiresAt <= Date.now()) { uni.removeStorageSync(key); return null; } return envelope.value; }, remove(key: string) { uni.removeStorageSync(key); } }; let cachedTokenLogged = false; export const authStorage = { getToken() { const token = encryptedStorage.get(APP_CONFIG.STORAGE_TOKEN_KEY) || ''; if (token && !cachedTokenLogged) { cachedTokenLogged = true; console.log('[cashier] token:', token); } return token; }, setToken(token: string, expiresInSeconds = 0) { encryptedStorage.set(APP_CONFIG.STORAGE_TOKEN_KEY, token, expiresInSeconds); cachedTokenLogged = true; console.log('[cashier] token:', token); }, clearToken() { encryptedStorage.remove(APP_CONFIG.STORAGE_TOKEN_KEY); cachedTokenLogged = false; } };