256 lines
7.6 KiB
TypeScript
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;
|
|
}
|