elearning/frontend_management/services/auth.service.ts

256 lines
7.6 KiB
TypeScript

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<LoginResponse> {
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<LoginResponse> {
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<LoginResponse> {
const config = useRuntimeConfig();
try {
const response = await $fetch<ApiLoginResponse>('/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<void> {
// 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<void> {
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<void> {
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<void> {
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;
}