mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-03 11:20:50 +08:00
feat: initialize new React application structure with TypeScript, ESLint, and Prettier configurations, while removing legacy files and adding new components and pages for enhanced functionality
This commit is contained in:
111
src/services/storage/secureStorage.ts
Normal file
111
src/services/storage/secureStorage.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* 安全存储服务
|
||||
* 基于原项目 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();
|
||||
Reference in New Issue
Block a user