export interface LoginRequest { email: string; password: string; } // API Response structure (from backend) export interface ApiLoginResponse { token: string; refreshToken: string; user: { id: number; username: string; email: string; updated_at: string; created_at: string; role: { code: string; name: { en: string; th: string; }; }; profile: { prefix: { en: string; th: string; }; first_name: string; last_name: string; phone: string | null; avatar_url: string | null; birth_date: string | null; }; }; } // Frontend User structure export interface LoginResponse { token: string; refreshToken: string; user: { id: string; email: string; firstName: string; lastName: string; role: string; }; } // Mock data for development const MOCK_USERS = [ { email: 'admin@elearning.local', password: 'password', user: { id: '1', email: 'admin@elearning.local', firstName: 'ผู้ดูแล', lastName: 'ระบบ', role: 'ADMIN' } }, { email: 'instructor@elearning.local', password: 'password', user: { id: '2', email: 'instructor@elearning.local', firstName: 'อาจารย์', lastName: 'ทดสอบ', role: 'INSTRUCTOR' } } ]; export const authService = { async login(email: string, password: string): Promise { const config = useRuntimeConfig(); const useMockData = config.public.useMockData as boolean; // Use Mock Data if (useMockData) { return this.mockLogin(email, password); } // Use Real API return this.apiLogin(email, password); }, // Mock login for development async mockLogin(email: string, password: string): Promise { await new Promise(resolve => setTimeout(resolve, 500)); // Simulate delay const mockUser = MOCK_USERS.find(u => u.email === email); if (!mockUser || mockUser.password !== password) { throw new Error('อีเมลหรือรหัสผ่านไม่ถูกต้อง'); } return { token: 'mock-jwt-token', refreshToken: 'mock-refresh-token', user: mockUser.user }; }, // Real API login async apiLogin(email: string, password: string): Promise { const config = useRuntimeConfig(); try { const response = await $fetch('/api/auth/login', { method: 'POST', baseURL: config.public.apiBaseUrl as string, body: { email, password } }); // Check if user role is STUDENT - block login if (response.user.role.code === 'STUDENT') { throw new Error('ไม่สามารถเข้าสู่ระบบได้ ระบบนี้สำหรับผู้สอนและผู้ดูแลระบบเท่านั้น'); } // Transform API response to frontend format return { token: response.token, refreshToken: response.refreshToken, user: { id: response.user.id.toString(), email: response.user.email, firstName: response.user.profile.first_name, lastName: response.user.profile.last_name, role: response.user.role.code } }; } catch (error: any) { // Re-throw custom errors (like STUDENT role block) if (error.message && !error.response) { throw error; } // Handle API errors if (error.response?.status === 401) { throw new Error('อีเมลหรือรหัสผ่านไม่ถูกต้อง'); } throw new Error('เกิดข้อผิดพลาดในการเข้าสู่ระบบ'); } }, async logout(): Promise { // Clear cookies const tokenCookie = useCookie('token'); const refreshTokenCookie = useCookie('refreshToken'); const userCookie = useCookie('user'); tokenCookie.value = null; refreshTokenCookie.value = null; userCookie.value = null; }, async forgotPassword(email: string): Promise { const config = useRuntimeConfig(); const useMockData = config.public.useMockData as boolean; if (useMockData) { // Mock: simulate sending email await new Promise(resolve => setTimeout(resolve, 1000)); return; } // Real API await $fetch('/api/auth/reset-request', { method: 'POST', baseURL: config.public.apiBaseUrl as string, body: { email } }); }, async resetPassword(token: string, password: string): Promise { const config = useRuntimeConfig(); const useMockData = config.public.useMockData as boolean; if (useMockData) { // Mock: simulate reset password await new Promise(resolve => setTimeout(resolve, 1000)); return; } // Real API await $fetch('/api/auth/reset-password', { method: 'POST', baseURL: config.public.apiBaseUrl as string, body: { token, password } }); }, async registerInstructor(data: RegisterInstructorRequest): Promise { const config = useRuntimeConfig(); const useMockData = config.public.useMockData as boolean; if (useMockData) { // Mock: simulate registration await new Promise(resolve => setTimeout(resolve, 1000)); return; } // Real API await $fetch('/api/auth/register-instructor', { method: 'POST', baseURL: config.public.apiBaseUrl as string, body: data }); }, async refreshToken(currentRefreshToken: string): Promise<{ token: string; refreshToken: string }> { const config = useRuntimeConfig(); const useMockData = config.public.useMockData as boolean; if (useMockData) { // Mock: return new tokens await new Promise(resolve => setTimeout(resolve, 500)); return { token: 'mock-new-jwt-token-' + Date.now(), refreshToken: 'mock-new-refresh-token-' + Date.now() }; } if (!currentRefreshToken) { throw new Error('No refresh token available'); } // Real API const response = await $fetch<{ token: string; refreshToken: string }>('/api/auth/refresh', { method: 'POST', baseURL: config.public.apiBaseUrl as string, body: { refreshToken: currentRefreshToken } }); return response; } }; // Register Instructor Request export interface RegisterInstructorRequest { username: string; email: string; password: string; first_name: string; last_name: string; prefix: { en: string; th: string; }; phone: string; }