veza/apps/web/src/services/authService.ts
senke ae586f6134 Phase 2 stabilisation: code mort, Modal→Dialog, feature flags, tests, router split, Rust legacy
Bloc A - Code mort:
- Suppression Studio (components, views, features)
- Suppression gamification + services mock (projectService, storageService, gamificationService)
- Mise à jour Sidebar, Navbar, locales

Bloc B - Frontend:
- Suppression modal.tsx deprecated, Modal.stories (doublon Dialog)
- Feature flags: PLAYLIST_SEARCH, PLAYLIST_RECOMMENDATIONS, ROLE_MANAGEMENT = true
- Suppression 19 tests orphelins, retrait exclusions vitest.config

Bloc C - Backend:
- Extraction routes_auth.go depuis router.go

Bloc D - Rust:
- Suppression security_legacy.rs (code mort, patterns déjà dans security/)
2026-02-14 17:23:32 +01:00

117 lines
3.1 KiB
TypeScript

import { apiClient } from '@/services/api/client';
import { User, UserDTO } from '../types';
import { logger } from '@/utils/logger';
export interface AuthLoginResult {
user: User;
token: { access_token: string; refresh_token: string };
}
export interface AuthRegisterResult {
user: User;
token: { access_token: string; refresh_token: string };
}
export interface LoginCredentials {
email: string;
password: string;
remember_me?: boolean;
}
export interface RegisterData {
username: string;
email: string;
password: string;
first_name?: string;
last_name?: string;
}
// Helper to map Backend DTO to Frontend Model
const mapUserDTO = (dto: UserDTO): User => ({
id: dto.id,
username: dto.username,
email: dto.email,
first_name: dto.first_name,
last_name: dto.last_name,
avatar: dto.avatar || 'https://via.placeholder.com/200',
banner: dto.banner,
bio: dto.bio,
location: dto.location,
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',
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(),
tier: dto.is_verified ? 'Pro' : 'Free',
stats: { followers: 0, following: 0, tracks: 0, plays: 0 },
});
export const authService = {
login: async (credentials: LoginCredentials): Promise<AuthLoginResult> => {
const response = await apiClient.post<{
user: UserDTO;
access_token: string;
refresh_token: string;
}>('/auth/login', credentials);
const data = response.data;
return {
user: mapUserDTO(data.user),
token: {
access_token: data.access_token,
refresh_token: data.refresh_token,
},
};
},
register: async (data: RegisterData): Promise<AuthRegisterResult> => {
const response = await apiClient.post<{
user: UserDTO;
access_token: string;
refresh_token: string;
}>('/auth/register', data);
const payload = response.data;
return {
user: mapUserDTO(payload.user),
token: {
access_token: payload.access_token,
refresh_token: payload.refresh_token,
},
};
},
logout: async () => {
try {
await apiClient.post('/auth/logout');
} catch (e) {
logger.warn('Logout failed on server', { error: e });
}
},
getCurrentUser: async () => {
const response = await apiClient.get<{ user: UserDTO }>('/auth/me');
return mapUserDTO(response.data.user);
},
checkUsername: async (username: string) => {
// Assuming endpoint returns { available: boolean }
const response = await apiClient.get<{ available: boolean }>(
`/auth/check-username?username=${username}`,
);
return response.data;
},
verifyEmail: (token: string) =>
apiClient.post('/auth/verify-email', { token }),
resendVerification: (email: string) =>
apiClient.post('/auth/resend-verification', { email }),
};