feat: 实现安全存储和批量导入功能增强
refactor(前端): 重构认证和存储逻辑使用secureStorage feat(前端): 添加安全存储工具和日志工具 feat(前端): 增强批量导入功能支持服务器和交换机设备 fix(后端): 改进设备端口和网卡批量导入接口 docs: 更新导入模板和操作说明
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import secureStorage, { USER_KEY } from './secureStorage';
|
||||
|
||||
export const debounce = (func, wait) => {
|
||||
let timeout;
|
||||
return function executedFunction(...args) {
|
||||
@@ -23,8 +25,8 @@ export const throttle = (func, limit) => {
|
||||
|
||||
export const getUserFromStorage = () => {
|
||||
try {
|
||||
const userStr = localStorage.getItem('user');
|
||||
return userStr ? JSON.parse(userStr) : {};
|
||||
const user = secureStorage.get(USER_KEY);
|
||||
return user || {};
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
const isDev = import.meta.env.DEV;
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
export const logger = {
|
||||
log: isDev ? console.log.bind(console) : noop,
|
||||
warn: isDev ? console.warn.bind(console) : noop,
|
||||
error: console.error.bind(console),
|
||||
info: isDev ? console.info.bind(console) : noop,
|
||||
debug: isDev ? console.debug.bind(console) : noop,
|
||||
|
||||
group: isDev ? console.group.bind(console) : noop,
|
||||
groupEnd: isDev ? console.groupEnd.bind(console) : noop,
|
||||
groupCollapsed: isDev ? console.groupCollapsed.bind(console) : noop,
|
||||
|
||||
table: isDev ? console.table.bind(console) : noop,
|
||||
trace: isDev ? console.trace.bind(console) : noop,
|
||||
time: isDev ? console.time.bind(console) : noop,
|
||||
timeEnd: isDev ? console.timeEnd.bind(console) : noop,
|
||||
timeLog: isDev ? console.timeLog.bind(console) : noop,
|
||||
|
||||
clear: isDev ? console.clear.bind(console) : noop,
|
||||
};
|
||||
|
||||
export default logger;
|
||||
@@ -0,0 +1,111 @@
|
||||
const STORAGE_PREFIX = 'idc_';
|
||||
const ENCRYPTION_ENABLED = import.meta.env.PROD;
|
||||
|
||||
const simpleEncrypt = (text) => {
|
||||
if (!ENCRYPTION_ENABLED) return text;
|
||||
|
||||
const key = import.meta.env.VITE_STORAGE_KEY || 'idc_default_secret_key_2024';
|
||||
let result = '';
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
result += String.fromCharCode(text.charCodeAt(i) ^ key.charCodeAt(i % key.length));
|
||||
}
|
||||
return btoa(encodeURIComponent(result));
|
||||
};
|
||||
|
||||
const simpleDecrypt = (encrypted) => {
|
||||
if (!ENCRYPTION_ENABLED) return encrypted;
|
||||
|
||||
try {
|
||||
const key = import.meta.env.VITE_STORAGE_KEY || 'idc_default_secret_key_2024';
|
||||
const decoded = decodeURIComponent(atob(encrypted));
|
||||
let result = '';
|
||||
for (let i = 0; i < decoded.length; i++) {
|
||||
result += String.fromCharCode(decoded.charCodeAt(i) ^ key.charCodeAt(i % key.length));
|
||||
}
|
||||
return result;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const secureStorage = {
|
||||
set: (key, value, options = {}) => {
|
||||
try {
|
||||
const storageKey = `${STORAGE_PREFIX}${key}`;
|
||||
const data = {
|
||||
value,
|
||||
timestamp: Date.now(),
|
||||
expiry: options.expiry || null,
|
||||
};
|
||||
const serialized = JSON.stringify(data);
|
||||
const encrypted = simpleEncrypt(serialized);
|
||||
localStorage.setItem(storageKey, encrypted);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('[SecureStorage] Set error:', error);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
get: (key) => {
|
||||
try {
|
||||
const storageKey = `${STORAGE_PREFIX}${key}`;
|
||||
const encrypted = localStorage.getItem(storageKey);
|
||||
|
||||
if (!encrypted) return null;
|
||||
|
||||
const decrypted = simpleDecrypt(encrypted);
|
||||
if (!decrypted) {
|
||||
localStorage.removeItem(storageKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
const data = JSON.parse(decrypted);
|
||||
|
||||
if (data.expiry && Date.now() > data.expiry) {
|
||||
localStorage.removeItem(storageKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
return data.value;
|
||||
} catch (error) {
|
||||
console.error('[SecureStorage] Get error:', error);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
try {
|
||||
const storageKey = `${STORAGE_PREFIX}${key}`;
|
||||
localStorage.removeItem(storageKey);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('[SecureStorage] Remove error:', error);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
clear: () => {
|
||||
try {
|
||||
const keys = [];
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i);
|
||||
if (key && key.startsWith(STORAGE_PREFIX)) {
|
||||
keys.push(key);
|
||||
}
|
||||
}
|
||||
keys.forEach((key) => localStorage.removeItem(key));
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('[SecureStorage] Clear error:', error);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const TOKEN_KEY = 'token';
|
||||
export const USER_KEY = 'user';
|
||||
export const USER_ID_KEY = 'userId';
|
||||
export const TICKET_COLUMNS_KEY = 'ticketVisibleColumns';
|
||||
|
||||
export default secureStorage;
|
||||
Reference in New Issue
Block a user