Files
Cli-Proxy-API-Management-Ce…/src/services/storage/secureStorage.ts

112 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 安全存储服务
* 基于原项目 src/utils/secure-storage.js
*/
import { encryptData, decryptData } from '@/utils/encryption';
interface StorageOptions {
encrypt?: boolean;
}
class SecureStorageService {
/**
* 存储数据
*/
setItem(key: string, value: any, options: StorageOptions = {}): void {
const { encrypt = true } = options;
if (value === null || value === undefined) {
this.removeItem(key);
return;
}
const stringValue = JSON.stringify(value);
const storedValue = encrypt ? encryptData(stringValue) : stringValue;
localStorage.setItem(key, storedValue);
}
/**
* 获取数据
*/
getItem<T = any>(key: string, options: StorageOptions = {}): T | null {
const { encrypt = true } = options;
const raw = localStorage.getItem(key);
if (raw === null) return null;
try {
const decrypted = encrypt ? decryptData(raw) : raw;
return JSON.parse(decrypted) as T;
} catch {
// JSON解析失败,尝试兼容旧的纯字符串数据 (非JSON格式)
try {
// 如果是加密的,尝试解密后直接返回
if (encrypt && raw.startsWith('enc::v1::')) {
const decrypted = decryptData(raw);
// 解密后如果还不是JSON,返回原始字符串
return decrypted as T;
}
// 非加密的纯字符串,直接返回
return raw as T;
} catch {
// 完全失败,静默返回null (避免控制台污染)
return null;
}
}
}
/**
* 删除数据
*/
removeItem(key: string): void {
localStorage.removeItem(key);
}
/**
* 清空所有数据
*/
clear(): void {
localStorage.clear();
}
/**
* 迁移旧的明文缓存为加密格式
*/
migratePlaintextKeys(keys: string[]): void {
keys.forEach((key) => {
const raw = localStorage.getItem(key);
if (!raw) return;
// 如果已经是加密格式,跳过
if (raw.startsWith('enc::v1::')) {
return;
}
let parsed: any = raw;
try {
parsed = JSON.parse(raw);
} catch {
// 原值不是 JSON直接使用字符串
parsed = raw;
}
try {
this.setItem(key, parsed);
} catch (error) {
console.warn(`Failed to migrate key "${key}":`, error);
}
});
}
/**
* 检查键是否存在
*/
hasItem(key: string): boolean {
return localStorage.getItem(key) !== null;
}
}
export const secureStorage = new SecureStorageService();