import { apiClient } from '@/services/api/client'; import axios, { AxiosError } from 'axios'; import type { LoginFormData, RegisterFormData, ForgotPasswordFormData, ResetPasswordFormData, } from '../types'; export interface AuthResponse { user: { id: number; email: string; username?: string; }; token: { access_token: string; refresh_token: string; expires_in: number; }; } export interface ApiError { message: string; code?: string; details?: Record; } /** * Gère les erreurs API de manière standardisée */ function handleApiError(error: unknown): never { if (axios.isAxiosError(error)) { const axiosError = error as AxiosError<{ error?: string; message?: string }>; if (axiosError.response) { // Erreur de réponse du serveur const errorMessage = axiosError.response.data?.error || axiosError.response.data?.message || 'An error occurred'; const apiError: ApiError = { message: errorMessage, code: axiosError.response.status.toString(), details: axiosError.response.data as Record, }; throw apiError; } else if (axiosError.request) { // Requête envoyée mais pas de réponse throw { message: 'Network error: Unable to connect to server', code: 'NETWORK_ERROR', } as ApiError; } } // Erreur inconnue throw { message: error instanceof Error ? error.message : 'An unexpected error occurred', code: 'UNKNOWN_ERROR', } as ApiError; } /** * Authentifie un utilisateur avec email et mot de passe * @param data - Données de connexion (email, password) * @returns Promise avec les tokens et les informations utilisateur * @throws ApiError en cas d'erreur */ export async function login(data: LoginFormData): Promise { try { const response = await apiClient.post('/auth/login', data); return response.data; } catch (error) { return handleApiError(error); } } /** * Enregistre un nouvel utilisateur * @param data - Données d'inscription (email, password, username) * @returns Promise avec les tokens et les informations utilisateur * @throws ApiError en cas d'erreur */ export async function register(data: RegisterFormData): Promise { try { const response = await apiClient.post('/auth/register', { email: data.email, password: data.password, password_confirm: data.confirmPassword, // Envoyer la confirmation du mot de passe username: data.username, }); return response.data; } catch (error) { return handleApiError(error); } } /** * Déconnecte l'utilisateur actuel * @throws ApiError en cas d'erreur */ export async function logout(): Promise { try { await apiClient.post('/auth/logout'); } catch (error) { return handleApiError(error); } } /** * Rafraîchit le token d'accès avec un refresh token * @param refreshToken - Le refresh token * @returns Promise avec les nouveaux tokens et les informations utilisateur * @throws ApiError en cas d'erreur */ export async function refreshToken(refreshToken: string): Promise { try { const response = await apiClient.post('/auth/refresh', { refreshToken, }); return response.data; } catch (error) { return handleApiError(error); } } /** * Demande une réinitialisation de mot de passe * @param data - Données contenant l'email * @throws ApiError en cas d'erreur */ export async function requestPasswordReset( data: ForgotPasswordFormData ): Promise { try { await apiClient.post('/auth/password/reset-request', data); } catch (error) { return handleApiError(error); } } /** * Réinitialise le mot de passe avec un token * @param data - Données contenant le token et le nouveau mot de passe * @throws ApiError en cas d'erreur */ export async function resetPassword(data: ResetPasswordFormData): Promise { try { await apiClient.post('/auth/password/reset', { token: data.token, password: data.password, }); } catch (error) { return handleApiError(error); } } /** * Vérifie l'email avec un token de vérification * @param token - Token de vérification * @throws ApiError en cas d'erreur */ export async function verifyEmail(token: string): Promise { try { await apiClient.get(`/auth/verify-email?token=${token}`); } catch (error) { return handleApiError(error); } } /** * Renvoie l'email de vérification * @param email - Email de l'utilisateur * @throws ApiError en cas d'erreur */ export async function resendVerificationEmail(email: string): Promise { try { await apiClient.post('/auth/resend-verification', { email }); } catch (error) { return handleApiError(error); } } /** * Vérifie la disponibilité d'un nom d'utilisateur * @param username - Le nom d'utilisateur à vérifier * @returns Promise avec true si disponible, false sinon * @throws ApiError en cas d'erreur */ export async function checkUsernameAvailability(username: string): Promise { try { const response = await apiClient.get<{ available: boolean }>(`/auth/check-username?username=${encodeURIComponent(username)}`); return response.data.available; } catch (error) { return handleApiError(error); } }