feat: Implement user authentication, admin user management, and role-based access control.
This commit is contained in:
parent
8a2ca592bc
commit
38648581ec
19 changed files with 1762 additions and 514 deletions
358
frontend_management/services/admin.service.ts
Normal file
358
frontend_management/services/admin.service.ts
Normal file
|
|
@ -0,0 +1,358 @@
|
|||
// API Response structure for user list
|
||||
export interface AdminUserResponse {
|
||||
id: number;
|
||||
username: string;
|
||||
email: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
role: {
|
||||
code: string;
|
||||
name: {
|
||||
en: string;
|
||||
th: string;
|
||||
};
|
||||
};
|
||||
profile: {
|
||||
prefix: {
|
||||
en: string;
|
||||
th: string;
|
||||
};
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
avatar_url: string | null;
|
||||
birth_date: string | null;
|
||||
phone: string | null;
|
||||
};
|
||||
}
|
||||
|
||||
export interface UsersListResponse {
|
||||
code: number;
|
||||
message: string;
|
||||
data: AdminUserResponse[];
|
||||
}
|
||||
|
||||
// Mock data for development
|
||||
const MOCK_USERS: AdminUserResponse[] = [
|
||||
{
|
||||
id: 1,
|
||||
username: 'admin',
|
||||
email: 'admin@elearning.local',
|
||||
created_at: '2024-01-01T00:00:00Z',
|
||||
updated_at: '2024-01-01T00:00:00Z',
|
||||
role: { code: 'ADMIN', name: { en: 'Administrator', th: 'ผู้ดูแลระบบ' } },
|
||||
profile: {
|
||||
prefix: { en: 'Mr.', th: 'นาย' },
|
||||
first_name: 'Admin',
|
||||
last_name: 'User',
|
||||
avatar_url: null,
|
||||
birth_date: null,
|
||||
phone: '0812345678'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
username: 'instructor',
|
||||
email: 'instructor@elearning.local',
|
||||
created_at: '2024-01-01T00:00:00Z',
|
||||
updated_at: '2024-01-01T00:00:00Z',
|
||||
role: { code: 'INSTRUCTOR', name: { en: 'Instructor', th: 'ผู้สอน' } },
|
||||
profile: {
|
||||
prefix: { en: 'Mr.', th: 'นาย' },
|
||||
first_name: 'John',
|
||||
last_name: 'Instructor',
|
||||
avatar_url: null,
|
||||
birth_date: null,
|
||||
phone: '0812345679'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
username: 'student',
|
||||
email: 'student@elearning.local',
|
||||
created_at: '2024-01-01T00:00:00Z',
|
||||
updated_at: '2024-01-01T00:00:00Z',
|
||||
role: { code: 'STUDENT', name: { en: 'Student', th: 'นักเรียน' } },
|
||||
profile: {
|
||||
prefix: { en: 'Ms.', th: 'นางสาว' },
|
||||
first_name: 'Jane',
|
||||
last_name: 'Student',
|
||||
avatar_url: null,
|
||||
birth_date: null,
|
||||
phone: '0812345680'
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
// Helper function to get auth token from cookie or localStorage
|
||||
const getAuthToken = (): string => {
|
||||
const tokenCookie = useCookie('token');
|
||||
return tokenCookie.value || '';
|
||||
};
|
||||
|
||||
export const adminService = {
|
||||
async getUsers(): Promise<AdminUserResponse[]> {
|
||||
const config = useRuntimeConfig();
|
||||
const useMockData = config.public.useMockData as boolean;
|
||||
|
||||
if (useMockData) {
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
return MOCK_USERS;
|
||||
}
|
||||
|
||||
const token = getAuthToken();
|
||||
const response = await $fetch<UsersListResponse>('/api/admin/usermanagement/users', {
|
||||
baseURL: config.public.apiBaseUrl as string,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
return response.data;
|
||||
},
|
||||
|
||||
async getUserById(id: number): Promise<AdminUserResponse> {
|
||||
const config = useRuntimeConfig();
|
||||
const useMockData = config.public.useMockData as boolean;
|
||||
|
||||
if (useMockData) {
|
||||
await new Promise(resolve => setTimeout(resolve, 300));
|
||||
const user = MOCK_USERS.find(u => u.id === id);
|
||||
if (!user) throw new Error('User not found');
|
||||
return user;
|
||||
}
|
||||
|
||||
const token = getAuthToken();
|
||||
const response = await $fetch<AdminUserResponse>(`/api/admin/usermanagement/users/${id}`, {
|
||||
baseURL: config.public.apiBaseUrl as string,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
async updateUserRole(userId: number, roleId: number): Promise<void> {
|
||||
const config = useRuntimeConfig();
|
||||
const useMockData = config.public.useMockData as boolean;
|
||||
|
||||
if (useMockData) {
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
return;
|
||||
}
|
||||
|
||||
const token = getAuthToken();
|
||||
await $fetch(`/api/admin/usermanagement/role/${userId}`, {
|
||||
method: 'PUT',
|
||||
baseURL: config.public.apiBaseUrl as string,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
body: {
|
||||
id: userId,
|
||||
role_id: roleId
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async deleteUser(userId: number): Promise<void> {
|
||||
const config = useRuntimeConfig();
|
||||
const useMockData = config.public.useMockData as boolean;
|
||||
|
||||
if (useMockData) {
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
return;
|
||||
}
|
||||
|
||||
const token = getAuthToken();
|
||||
await $fetch(`/api/admin/usermanagement/users/${userId}`, {
|
||||
method: 'DELETE',
|
||||
baseURL: config.public.apiBaseUrl as string,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// ============ Categories ============
|
||||
async getCategories(): Promise<CategoryResponse[]> {
|
||||
const config = useRuntimeConfig();
|
||||
const useMockData = config.public.useMockData as boolean;
|
||||
|
||||
if (useMockData) {
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
return MOCK_CATEGORIES;
|
||||
}
|
||||
|
||||
const token = getAuthToken();
|
||||
const response = await $fetch<CategoriesListResponse>('/api/admin/categories', {
|
||||
baseURL: config.public.apiBaseUrl as string,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
return response.data.categories;
|
||||
},
|
||||
|
||||
async createCategory(data: CreateCategoryRequest): Promise<CategoryResponse> {
|
||||
const config = useRuntimeConfig();
|
||||
const useMockData = config.public.useMockData as boolean;
|
||||
|
||||
if (useMockData) {
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
return { ...MOCK_CATEGORIES[0], id: Date.now() };
|
||||
}
|
||||
|
||||
const token = getAuthToken();
|
||||
const response = await $fetch<CategoryResponse>('/api/admin/categories', {
|
||||
method: 'POST',
|
||||
baseURL: config.public.apiBaseUrl as string,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
body: data
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
async updateCategory(id: number, data: UpdateCategoryRequest): Promise<CategoryResponse> {
|
||||
const config = useRuntimeConfig();
|
||||
const useMockData = config.public.useMockData as boolean;
|
||||
|
||||
if (useMockData) {
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
return { ...MOCK_CATEGORIES[0], id };
|
||||
}
|
||||
|
||||
const token = getAuthToken();
|
||||
const response = await $fetch<CategoryResponse>(`/api/admin/categories/${id}`, {
|
||||
method: 'PUT',
|
||||
baseURL: config.public.apiBaseUrl as string,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
body: data
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
async deleteCategory(id: number): Promise<void> {
|
||||
const config = useRuntimeConfig();
|
||||
const useMockData = config.public.useMockData as boolean;
|
||||
|
||||
if (useMockData) {
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
return;
|
||||
}
|
||||
|
||||
const token = getAuthToken();
|
||||
await $fetch(`/api/admin/categories/${id}`, {
|
||||
method: 'DELETE',
|
||||
baseURL: config.public.apiBaseUrl as string,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Category interfaces
|
||||
export interface CategoryResponse {
|
||||
id: number;
|
||||
name: {
|
||||
en: string;
|
||||
th: string;
|
||||
};
|
||||
slug: string;
|
||||
description: {
|
||||
en: string;
|
||||
th: string;
|
||||
};
|
||||
icon: string;
|
||||
sort_order: number;
|
||||
is_active: boolean;
|
||||
created_at: string;
|
||||
created_by: number;
|
||||
updated_at: string;
|
||||
updated_by: number | null;
|
||||
}
|
||||
|
||||
export interface CategoriesListResponse {
|
||||
code: number;
|
||||
message: string;
|
||||
data: {
|
||||
categories: CategoryResponse[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface CreateCategoryRequest {
|
||||
name: {
|
||||
en: string;
|
||||
th: string;
|
||||
};
|
||||
slug: string;
|
||||
description: {
|
||||
en: string;
|
||||
th: string;
|
||||
};
|
||||
created_by?: number;
|
||||
}
|
||||
|
||||
export interface UpdateCategoryRequest {
|
||||
id: number;
|
||||
name: {
|
||||
en: string;
|
||||
th: string;
|
||||
};
|
||||
slug: string;
|
||||
description: {
|
||||
en: string;
|
||||
th: string;
|
||||
};
|
||||
}
|
||||
|
||||
// Mock categories
|
||||
const MOCK_CATEGORIES: CategoryResponse[] = [
|
||||
{
|
||||
id: 1,
|
||||
name: { en: 'Web Development', th: 'การพัฒนาเว็บไซต์' },
|
||||
slug: 'web-development',
|
||||
description: { en: 'Learn web development', th: 'หลักสูตรเกี่ยวกับการพัฒนาเว็บไซต์และเว็บแอปพลิเคชัน' },
|
||||
icon: 'code',
|
||||
sort_order: 1,
|
||||
is_active: true,
|
||||
created_at: '2024-01-15T00:00:00Z',
|
||||
created_by: 1,
|
||||
updated_at: '2024-01-15T00:00:00Z',
|
||||
updated_by: null
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: { en: 'Mobile Development', th: 'การพัฒนาแอปพลิเคชันมือถือ' },
|
||||
slug: 'mobile-development',
|
||||
description: { en: 'Learn mobile app development', th: 'หลักสูตรเกี่ยวกับการพัฒนาแอปพลิเคชันบนมือถือ' },
|
||||
icon: 'smartphone',
|
||||
sort_order: 2,
|
||||
is_active: true,
|
||||
created_at: '2024-01-20T00:00:00Z',
|
||||
created_by: 1,
|
||||
updated_at: '2024-01-20T00:00:00Z',
|
||||
updated_by: null
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: { en: 'Database', th: 'ฐานข้อมูล' },
|
||||
slug: 'database',
|
||||
description: { en: 'Learn database management', th: 'หลักสูตรเกี่ยวกับการออกแบบและจัดการฐานข้อมูล' },
|
||||
icon: 'storage',
|
||||
sort_order: 3,
|
||||
is_active: true,
|
||||
created_at: '2024-02-01T00:00:00Z',
|
||||
created_by: 1,
|
||||
updated_at: '2024-02-01T00:00:00Z',
|
||||
updated_by: null
|
||||
}
|
||||
];
|
||||
|
|
@ -41,14 +41,72 @@ export interface LoginResponse {
|
|||
user: {
|
||||
id: string;
|
||||
email: string;
|
||||
fullName: 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', {
|
||||
|
|
@ -60,6 +118,11 @@ export const authService = {
|
|||
}
|
||||
});
|
||||
|
||||
// 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,
|
||||
|
|
@ -67,26 +130,68 @@ export const authService = {
|
|||
user: {
|
||||
id: response.user.id.toString(),
|
||||
email: response.user.email,
|
||||
fullName: `${response.user.profile.first_name} ${response.user.profile.last_name}`,
|
||||
role: response.user.role.code // Use role.code (ADMIN, INSTRUCTOR, etc.)
|
||||
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('Invalid credentials');
|
||||
throw new Error('อีเมลหรือรหัสผ่านไม่ถูกต้อง');
|
||||
}
|
||||
throw new Error('Login failed');
|
||||
throw new Error('เกิดข้อผิดพลาดในการเข้าสู่ระบบ');
|
||||
}
|
||||
},
|
||||
|
||||
async logout(): Promise<void> {
|
||||
// TODO: Call logout API if available
|
||||
// For now, just clear local storage
|
||||
if (process.client) {
|
||||
localStorage.removeItem('token');
|
||||
localStorage.removeItem('refreshToken');
|
||||
localStorage.removeItem('user');
|
||||
// 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 }
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
182
frontend_management/services/user.service.ts
Normal file
182
frontend_management/services/user.service.ts
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
// API Response structure from /api/user/me
|
||||
export interface UserProfileResponse {
|
||||
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;
|
||||
avatar_url: string | null;
|
||||
birth_date: string | null;
|
||||
phone: string | null;
|
||||
};
|
||||
}
|
||||
|
||||
// Request body for PUT /api/user/me
|
||||
export interface UpdateProfileRequest {
|
||||
prefix?: {
|
||||
en: string;
|
||||
th: string;
|
||||
};
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
phone?: string | null;
|
||||
avatar_url?: string | null;
|
||||
birth_date?: string | null;
|
||||
}
|
||||
|
||||
// Mock profile data for development
|
||||
const MOCK_PROFILES: Record<string, UserProfileResponse> = {
|
||||
'admin@elearning.local': {
|
||||
id: 1,
|
||||
username: 'admin',
|
||||
email: 'admin@elearning.local',
|
||||
updated_at: '2024-01-01T00:00:00Z',
|
||||
created_at: '2024-01-01T00:00:00Z',
|
||||
role: {
|
||||
code: 'ADMIN',
|
||||
name: { en: 'Administrator', th: 'ผู้ดูแลระบบ' }
|
||||
},
|
||||
profile: {
|
||||
prefix: { en: 'Mr.', th: 'นาย' },
|
||||
first_name: 'ผู้ดูแล',
|
||||
last_name: 'ระบบ',
|
||||
avatar_url: null,
|
||||
birth_date: null,
|
||||
phone: '081-234-5678'
|
||||
}
|
||||
},
|
||||
'instructor@elearning.local': {
|
||||
id: 2,
|
||||
username: 'instructor',
|
||||
email: 'instructor@elearning.local',
|
||||
updated_at: '2024-01-01T00:00:00Z',
|
||||
created_at: '2024-01-01T00:00:00Z',
|
||||
role: {
|
||||
code: 'INSTRUCTOR',
|
||||
name: { en: 'Instructor', th: 'ผู้สอน' }
|
||||
},
|
||||
profile: {
|
||||
prefix: { en: 'Mr.', th: 'นาย' },
|
||||
first_name: 'อาจารย์',
|
||||
last_name: 'ทดสอบ',
|
||||
avatar_url: null,
|
||||
birth_date: null,
|
||||
phone: '081-234-5678'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Helper function to get auth token from cookie
|
||||
const getAuthToken = (): string => {
|
||||
const tokenCookie = useCookie('token');
|
||||
return tokenCookie.value || '';
|
||||
};
|
||||
|
||||
export const userService = {
|
||||
async getProfile(): Promise<UserProfileResponse> {
|
||||
const config = useRuntimeConfig();
|
||||
const useMockData = config.public.useMockData as boolean;
|
||||
|
||||
if (useMockData) {
|
||||
return this.mockGetProfile();
|
||||
}
|
||||
|
||||
return this.apiGetProfile();
|
||||
},
|
||||
|
||||
// Mock get profile
|
||||
async mockGetProfile(): Promise<UserProfileResponse> {
|
||||
await new Promise(resolve => setTimeout(resolve, 300));
|
||||
|
||||
const userCookie = useCookie('user');
|
||||
if (!userCookie.value) throw new Error('User not found');
|
||||
|
||||
const user = typeof userCookie.value === 'string'
|
||||
? JSON.parse(userCookie.value)
|
||||
: userCookie.value;
|
||||
const mockProfile = MOCK_PROFILES[user.email];
|
||||
|
||||
if (!mockProfile) {
|
||||
throw new Error('Profile not found');
|
||||
}
|
||||
|
||||
return mockProfile;
|
||||
},
|
||||
|
||||
// Real API get profile
|
||||
async apiGetProfile(): Promise<UserProfileResponse> {
|
||||
const config = useRuntimeConfig();
|
||||
const token = getAuthToken();
|
||||
|
||||
const response = await $fetch<UserProfileResponse>('/api/user/me', {
|
||||
baseURL: config.public.apiBaseUrl as string,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
async updateProfile(data: UpdateProfileRequest): Promise<UserProfileResponse> {
|
||||
const config = useRuntimeConfig();
|
||||
const useMockData = config.public.useMockData as boolean;
|
||||
|
||||
if (useMockData) {
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
// In mock mode, just return the current profile with updates
|
||||
const profile = await this.mockGetProfile();
|
||||
return { ...profile, profile: { ...profile.profile, ...data } };
|
||||
}
|
||||
|
||||
const token = getAuthToken();
|
||||
const response = await $fetch<UserProfileResponse>('/api/user/me', {
|
||||
method: 'PUT',
|
||||
baseURL: config.public.apiBaseUrl as string,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
body: data
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
|
||||
async changePassword(oldPassword: string, newPassword: string): Promise<void> {
|
||||
const config = useRuntimeConfig();
|
||||
const useMockData = config.public.useMockData as boolean;
|
||||
|
||||
if (useMockData) {
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
// In mock mode, just simulate success
|
||||
return;
|
||||
}
|
||||
|
||||
const token = getAuthToken();
|
||||
await $fetch('/api/user/change-password', {
|
||||
method: 'POST',
|
||||
baseURL: config.public.apiBaseUrl as string,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
body: {
|
||||
oldPassword,
|
||||
newPassword
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue