// Auth service for handling authentication API calls export interface LoginRequest { email: string; password: string; } export interface RegisterRequest { username: string; email: string; password: string; } export interface User { id: string; username: string; email: string; displayName: string | null; avatarUrl: string | null; subscriptionType: string; } export interface AuthResponse { success: boolean; data?: { token: string; user: User; }; error?: string; } const API_BASE_URL = 'http://localhost:5008'; class AuthService { private async makeRequest( endpoint: string, options: RequestInit = {} ): Promise { const url = `${API_BASE_URL}/api/auth${endpoint}`; console.log('Making request to:', url) console.log('Request body:', options.body) const response = await fetch(url, { headers: { 'Content-Type': 'application/json', ...options.headers, }, ...options, }); if (!response.ok) { const errorData = await response.json().catch(() => ({ error: 'Network error' })); console.log('API Error Response:', errorData) // 處理驗證錯誤 (400 Bad Request) if (response.status === 400 && errorData.errors) { const validationErrors = Object.entries(errorData.errors) .map(([field, messages]: [string, any]) => `${field}: ${Array.isArray(messages) ? messages.join(', ') : messages}`) .join('\n'); throw new Error(validationErrors); } throw new Error(errorData.error || errorData.title || `HTTP ${response.status}`); } return response.json(); } async login(data: LoginRequest): Promise { try { const response = await this.makeRequest('/login', { method: 'POST', body: JSON.stringify(data), }); if (response.success && response.data?.token) { // Store token in localStorage localStorage.setItem('auth_token', response.data.token); localStorage.setItem('user_data', JSON.stringify(response.data.user)); } return response; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Login failed', }; } } async register(data: RegisterRequest): Promise { try { console.log('AuthService.register called with:', { username: data.username, email: data.email, password: data.password ? '[hidden]' : 'empty' }) const response = await this.makeRequest('/register', { method: 'POST', body: JSON.stringify(data), }); if (response.success && response.data?.token) { // Store token in localStorage localStorage.setItem('auth_token', response.data.token); localStorage.setItem('user_data', JSON.stringify(response.data.user)); } return response; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Registration failed', }; } } async logout(): Promise { localStorage.removeItem('auth_token'); localStorage.removeItem('user_data'); } getToken(): string | null { if (typeof window === 'undefined') return null; return localStorage.getItem('auth_token'); } getUser(): User | null { if (typeof window === 'undefined') return null; const userData = localStorage.getItem('user_data'); return userData ? JSON.parse(userData) : null; } isAuthenticated(): boolean { return this.getToken() !== null; } async checkAuthStatus(): Promise { const token = this.getToken(); if (!token) return false; try { await this.makeRequest('/status', { headers: { 'Authorization': `Bearer ${token}`, }, }); return true; } catch { // Token is invalid, clear it this.logout(); return false; } } } export const authService = new AuthService();