import React, { createContext, useContext, useState, useEffect } from 'react'; import { getSystemConfig } from '../lib/config'; import { CryptoService } from '../lib/crypto'; interface User { id: string email: string } interface AuthContextType { user: User | null token: string | null login: ( email: string, password: string ) => Promise<{ success: boolean message?: string userID?: string requiresOTP?: boolean }> register: ( email: string, password: string, betaCode?: string ) => Promise<{ success: boolean message?: string userID?: string otpSecret?: string qrCodeURL?: string }> verifyOTP: ( userID: string, otpCode: string ) => Promise<{ success: boolean; message?: string }> completeRegistration: ( userID: string, otpCode: string ) => Promise<{ success: boolean; message?: string }> logout: () => void isLoading: boolean } const AuthContext = createContext(undefined) export function AuthProvider({ children }: { children: React.ReactNode }) { const [user, setUser] = useState(null) const [token, setToken] = useState(null) const [isLoading, setIsLoading] = useState(true) useEffect(() => { const savedToken = localStorage.getItem('auth_token') const savedUser = localStorage.getItem('auth_user') if (savedToken && savedUser) { setToken(savedToken) setUser(JSON.parse(savedUser)) } setIsLoading(false) }, []) const login = async (email: string, password: string) => { try { const systemConfig = await getSystemConfig() if (!systemConfig.rsa_public_key) { throw new Error('系统未配置登录所需的RSA公钥') } await CryptoService.initialize(systemConfig.rsa_public_key) const sessionId = sessionStorage.getItem('session_id') || '' const requestBody = { email_encrypted: await CryptoService.encryptSensitiveData( email, email, sessionId ), password_encrypted: await CryptoService.encryptSensitiveData( password, email, sessionId ), } const response = await fetch('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(requestBody), }) const data = await response.json() if (response.ok) { if (data.requires_otp) { return { success: true, userID: data.user_id, requiresOTP: true, message: data.message, } } } else { return { success: false, message: data.error } } } catch (error) { console.error('Login request failed:', error) return { success: false, message: '登录失败,请重试' } } return { success: false, message: '未知错误' } } const register = async ( email: string, password: string, betaCode?: string ) => { try { const requestBody: { email: string password: string beta_code?: string } = { email, password } if (betaCode) { requestBody.beta_code = betaCode } const response = await fetch('/api/register', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(requestBody), }) const data = await response.json() if (response.ok) { return { success: true, userID: data.user_id, otpSecret: data.otp_secret, qrCodeURL: data.qr_code_url, message: data.message, } } else { return { success: false, message: data.error } } } catch (error) { return { success: false, message: '注册失败,请重试' } } } const verifyOTP = async (userID: string, otpCode: string) => { try { const response = await fetch('/api/verify-otp', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ user_id: userID, otp_code: otpCode }), }) const data = await response.json() if (response.ok) { // 登录成功,保存token和用户信息 const userInfo = { id: data.user_id, email: data.email } setToken(data.token) setUser(userInfo) localStorage.setItem('auth_token', data.token) localStorage.setItem('auth_user', JSON.stringify(userInfo)) // 跳转到配置页面 window.history.pushState({}, '', '/traders') window.dispatchEvent(new PopStateEvent('popstate')) return { success: true, message: data.message } } else { return { success: false, message: data.error } } } catch (error) { return { success: false, message: 'OTP验证失败,请重试' } } } const completeRegistration = async (userID: string, otpCode: string) => { try { const response = await fetch('/api/complete-registration', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ user_id: userID, otp_code: otpCode }), }) const data = await response.json() if (response.ok) { // 注册完成,自动登录 const userInfo = { id: data.user_id, email: data.email } setToken(data.token) setUser(userInfo) localStorage.setItem('auth_token', data.token) localStorage.setItem('auth_user', JSON.stringify(userInfo)) // 跳转到配置页面 window.history.pushState({}, '', '/traders') window.dispatchEvent(new PopStateEvent('popstate')) return { success: true, message: data.message } } else { return { success: false, message: data.error } } } catch (error) { return { success: false, message: '注册完成失败,请重试' } } } const logout = () => { setUser(null) setToken(null) localStorage.removeItem('auth_token') localStorage.removeItem('auth_user') } return ( {children} ) } export function useAuth() { const context = useContext(AuthContext) if (context === undefined) { throw new Error('useAuth must be used within an AuthProvider') } return context }