mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-18 02:30:51 +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:
201
src/stores/useAuthStore.ts
Normal file
201
src/stores/useAuthStore.ts
Normal file
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* 认证状态管理
|
||||
* 从原项目 src/modules/login.js 和 src/core/connection.js 迁移
|
||||
*/
|
||||
|
||||
import { create } from 'zustand';
|
||||
import { persist, createJSONStorage } from 'zustand/middleware';
|
||||
import type { AuthState, LoginCredentials, ConnectionStatus } from '@/types';
|
||||
import { STORAGE_KEY_AUTH } from '@/utils/constants';
|
||||
import { secureStorage } from '@/services/storage/secureStorage';
|
||||
import { apiClient } from '@/services/api/client';
|
||||
import { configApi } from '@/services/api/config';
|
||||
import { useConfigStore } from './useConfigStore';
|
||||
import { detectApiBaseFromLocation, normalizeApiBase } from '@/utils/connection';
|
||||
|
||||
interface AuthStoreState extends AuthState {
|
||||
connectionStatus: ConnectionStatus;
|
||||
connectionError: string | null;
|
||||
|
||||
// 操作
|
||||
login: (credentials: LoginCredentials) => Promise<void>;
|
||||
logout: () => void;
|
||||
checkAuth: () => Promise<boolean>;
|
||||
restoreSession: () => Promise<boolean>;
|
||||
updateServerVersion: (version: string | null, buildDate?: string | null) => void;
|
||||
updateConnectionStatus: (status: ConnectionStatus, error?: string | null) => void;
|
||||
}
|
||||
|
||||
export const useAuthStore = create<AuthStoreState>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
// 初始状态
|
||||
isAuthenticated: false,
|
||||
apiBase: '',
|
||||
managementKey: '',
|
||||
serverVersion: null,
|
||||
serverBuildDate: null,
|
||||
connectionStatus: 'disconnected',
|
||||
connectionError: null,
|
||||
|
||||
// 恢复会话并自动登录
|
||||
restoreSession: async () => {
|
||||
secureStorage.migratePlaintextKeys(['apiBase', 'apiUrl', 'managementKey']);
|
||||
|
||||
const wasLoggedIn = localStorage.getItem('isLoggedIn') === 'true';
|
||||
const legacyBase =
|
||||
secureStorage.getItem<string>('apiBase') ||
|
||||
secureStorage.getItem<string>('apiUrl', { encrypt: true });
|
||||
const legacyKey = secureStorage.getItem<string>('managementKey');
|
||||
|
||||
const { apiBase, managementKey } = get();
|
||||
const resolvedBase = normalizeApiBase(apiBase || legacyBase || detectApiBaseFromLocation());
|
||||
const resolvedKey = managementKey || legacyKey || '';
|
||||
|
||||
set({ apiBase: resolvedBase, managementKey: resolvedKey });
|
||||
apiClient.setConfig({ apiBase: resolvedBase, managementKey: resolvedKey });
|
||||
|
||||
if (wasLoggedIn && resolvedBase && resolvedKey) {
|
||||
try {
|
||||
await get().login({ apiBase: resolvedBase, managementKey: resolvedKey });
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.warn('Auto login failed:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
// 登录
|
||||
login: async (credentials) => {
|
||||
const apiBase = normalizeApiBase(credentials.apiBase);
|
||||
const managementKey = credentials.managementKey.trim();
|
||||
|
||||
try {
|
||||
set({ connectionStatus: 'connecting' });
|
||||
|
||||
// 配置 API 客户端
|
||||
apiClient.setConfig({
|
||||
apiBase,
|
||||
managementKey
|
||||
});
|
||||
|
||||
// 测试连接 - 获取配置
|
||||
await configApi.getConfig();
|
||||
|
||||
// 登录成功
|
||||
set({
|
||||
isAuthenticated: true,
|
||||
apiBase,
|
||||
managementKey,
|
||||
connectionStatus: 'connected',
|
||||
connectionError: null
|
||||
});
|
||||
localStorage.setItem('isLoggedIn', 'true');
|
||||
} catch (error: any) {
|
||||
set({
|
||||
connectionStatus: 'error',
|
||||
connectionError: error.message || 'Connection failed'
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
// 登出
|
||||
logout: () => {
|
||||
useConfigStore.getState().clearCache();
|
||||
set({
|
||||
isAuthenticated: false,
|
||||
apiBase: '',
|
||||
managementKey: '',
|
||||
serverVersion: null,
|
||||
serverBuildDate: null,
|
||||
connectionStatus: 'disconnected',
|
||||
connectionError: null
|
||||
});
|
||||
localStorage.removeItem('isLoggedIn');
|
||||
},
|
||||
|
||||
// 检查认证状态
|
||||
checkAuth: async () => {
|
||||
const { managementKey, apiBase } = get();
|
||||
|
||||
if (!managementKey || !apiBase) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// 重新配置客户端
|
||||
apiClient.setConfig({ apiBase, managementKey });
|
||||
|
||||
// 验证连接
|
||||
await configApi.getConfig();
|
||||
|
||||
set({
|
||||
isAuthenticated: true,
|
||||
connectionStatus: 'connected'
|
||||
});
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
set({
|
||||
isAuthenticated: false,
|
||||
connectionStatus: 'error'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
// 更新服务器版本
|
||||
updateServerVersion: (version, buildDate) => {
|
||||
set({ serverVersion: version || null, serverBuildDate: buildDate || null });
|
||||
},
|
||||
|
||||
// 更新连接状态
|
||||
updateConnectionStatus: (status, error = null) => {
|
||||
set({
|
||||
connectionStatus: status,
|
||||
connectionError: error
|
||||
});
|
||||
}
|
||||
}),
|
||||
{
|
||||
name: STORAGE_KEY_AUTH,
|
||||
storage: createJSONStorage(() => ({
|
||||
getItem: (name) => {
|
||||
const data = secureStorage.getItem<AuthStoreState>(name);
|
||||
return data ? JSON.stringify(data) : null;
|
||||
},
|
||||
setItem: (name, value) => {
|
||||
secureStorage.setItem(name, JSON.parse(value));
|
||||
},
|
||||
removeItem: (name) => {
|
||||
secureStorage.removeItem(name);
|
||||
}
|
||||
})),
|
||||
partialize: (state) => ({
|
||||
apiBase: state.apiBase,
|
||||
managementKey: state.managementKey,
|
||||
serverVersion: state.serverVersion,
|
||||
serverBuildDate: state.serverBuildDate
|
||||
})
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// 监听全局未授权事件
|
||||
if (typeof window !== 'undefined') {
|
||||
window.addEventListener('unauthorized', () => {
|
||||
useAuthStore.getState().logout();
|
||||
});
|
||||
|
||||
window.addEventListener(
|
||||
'server-version-update',
|
||||
((e: CustomEvent) => {
|
||||
const detail = e.detail || {};
|
||||
useAuthStore.getState().updateServerVersion(detail.version || null, detail.buildDate || null);
|
||||
}) as EventListener
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user