2026-01-07 18:39:21 +00:00
|
|
|
import { apiClient } from '@/services/api/client';
|
2026-01-07 09:33:52 +00:00
|
|
|
import { User, UserDTO } from '../types';
|
2026-01-07 10:15:48 +00:00
|
|
|
import { logger } from '@/utils/logger';
|
2026-01-07 09:33:52 +00:00
|
|
|
|
|
|
|
|
// Helper to map Backend DTO to Frontend Model
|
|
|
|
|
const mapUserDTO = (dto: UserDTO): User => ({
|
|
|
|
|
id: dto.id,
|
|
|
|
|
username: dto.username,
|
|
|
|
|
email: dto.email,
|
2026-01-07 18:39:21 +00:00
|
|
|
first_name: dto.first_name,
|
|
|
|
|
last_name: dto.last_name,
|
|
|
|
|
avatar: dto.avatar || 'https://via.placeholder.com/200',
|
2026-01-07 09:33:52 +00:00
|
|
|
banner: dto.banner,
|
|
|
|
|
bio: dto.bio,
|
|
|
|
|
location: dto.location,
|
2026-01-07 18:39:21 +00:00
|
|
|
roles: dto.role ? [dto.role] : ['USER'],
|
|
|
|
|
role: dto.role || 'user',
|
|
|
|
|
// Default boolean flags if missing in DTO
|
|
|
|
|
is_active: true,
|
|
|
|
|
is_verified: dto.is_verified ?? false,
|
|
|
|
|
is_admin: false,
|
|
|
|
|
is_public: true,
|
|
|
|
|
status: 'online',
|
2026-01-13 18:47:57 +00:00
|
|
|
created_at: dto.created_at
|
|
|
|
|
? new Date(dto.created_at).toISOString()
|
|
|
|
|
: new Date().toISOString(),
|
|
|
|
|
updated_at: dto.created_at
|
|
|
|
|
? new Date(dto.created_at).toISOString()
|
|
|
|
|
: new Date().toISOString(),
|
2026-01-07 18:39:21 +00:00
|
|
|
tier: dto.is_verified ? 'Pro' : 'Free',
|
2026-01-13 18:47:57 +00:00
|
|
|
stats: { followers: 0, following: 0, tracks: 0, plays: 0 },
|
2026-01-07 09:33:52 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export const authService = {
|
|
|
|
|
login: async (credentials: any) => {
|
2026-01-13 18:47:57 +00:00
|
|
|
const response = await apiClient.post<{
|
|
|
|
|
user: UserDTO;
|
|
|
|
|
access_token: string;
|
|
|
|
|
refresh_token: string;
|
|
|
|
|
}>('/auth/login', credentials);
|
2026-01-07 18:39:21 +00:00
|
|
|
// apiClient returns AxiosResponse, data is already unwrapped if success:true
|
|
|
|
|
const data = response.data;
|
|
|
|
|
// Handle both wrapped and unwrapped cases just in case, though apiClient handles unwrap
|
|
|
|
|
// If apiClient unwrapped it, data is the payload.
|
2026-01-07 09:33:52 +00:00
|
|
|
return {
|
2026-01-07 18:39:21 +00:00
|
|
|
user: mapUserDTO(data.user),
|
2026-01-13 18:47:57 +00:00
|
|
|
token: {
|
|
|
|
|
access_token: data.access_token,
|
|
|
|
|
refresh_token: data.refresh_token,
|
|
|
|
|
},
|
2026-01-07 09:33:52 +00:00
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
register: async (data: any) => {
|
2026-01-13 18:47:57 +00:00
|
|
|
const response = await apiClient.post<{
|
|
|
|
|
user: UserDTO;
|
|
|
|
|
access_token: string;
|
|
|
|
|
refresh_token: string;
|
|
|
|
|
}>('/auth/register', data);
|
2026-01-07 18:39:21 +00:00
|
|
|
const payload = response.data;
|
2026-01-07 09:33:52 +00:00
|
|
|
return {
|
2026-01-07 18:39:21 +00:00
|
|
|
user: mapUserDTO(payload.user),
|
2026-01-13 18:47:57 +00:00
|
|
|
token: {
|
|
|
|
|
access_token: payload.access_token,
|
|
|
|
|
refresh_token: payload.refresh_token,
|
|
|
|
|
},
|
2026-01-07 09:33:52 +00:00
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
logout: async () => {
|
|
|
|
|
try {
|
2026-01-07 18:39:21 +00:00
|
|
|
await apiClient.post('/auth/logout');
|
2026-01-07 09:33:52 +00:00
|
|
|
} catch (e) {
|
2026-01-07 10:15:48 +00:00
|
|
|
logger.warn('Logout failed on server', { error: e });
|
2026-01-07 09:33:52 +00:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getCurrentUser: async () => {
|
2026-01-07 18:39:21 +00:00
|
|
|
const response = await apiClient.get<{ user: UserDTO }>('/auth/me');
|
|
|
|
|
return mapUserDTO(response.data.user);
|
2026-01-07 09:33:52 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
checkUsername: async (username: string) => {
|
2026-01-07 10:15:48 +00:00
|
|
|
// Assuming endpoint returns { available: boolean }
|
2026-01-13 18:47:57 +00:00
|
|
|
const response = await apiClient.get<{ available: boolean }>(
|
|
|
|
|
`/auth/check-username?username=${username}`,
|
|
|
|
|
);
|
2026-01-07 18:39:21 +00:00
|
|
|
return response.data;
|
2026-01-07 09:33:52 +00:00
|
|
|
},
|
|
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
verifyEmail: (token: string) =>
|
|
|
|
|
apiClient.post('/auth/verify-email', { token }),
|
2026-01-07 09:33:52 +00:00
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
resendVerification: (email: string) =>
|
|
|
|
|
apiClient.post('/auth/resend-verification', { email }),
|
2026-01-07 09:33:52 +00:00
|
|
|
};
|