201 lines
5.3 KiB
TypeScript
201 lines
5.3 KiB
TypeScript
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<string, unknown>;
|
|
}
|
|
|
|
/**
|
|
* 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<string, unknown>,
|
|
};
|
|
|
|
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<AuthResponse> {
|
|
try {
|
|
const response = await apiClient.post<AuthResponse>('/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<AuthResponse> {
|
|
try {
|
|
const response = await apiClient.post<AuthResponse>('/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<void> {
|
|
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<AuthResponse> {
|
|
try {
|
|
const response = await apiClient.post<AuthResponse>('/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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<boolean> {
|
|
try {
|
|
const response = await apiClient.get<{ available: boolean }>(`/auth/check-username?username=${encodeURIComponent(username)}`);
|
|
return response.data.available;
|
|
} catch (error) {
|
|
return handleApiError(error);
|
|
}
|
|
}
|
|
|