first
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
// Created by: Claude
|
||||
// Date: 2026-01-03
|
||||
// Purpose: Service API pour les appels au serveur Mesh
|
||||
// Refs: client/CLAUDE.md, docs/protocol_events_v_2.md
|
||||
|
||||
import axios, { AxiosInstance } from 'axios'
|
||||
import { useAuthStore } from '../stores/authStore'
|
||||
|
||||
// URL du serveur (à configurer via variable d'environnement)
|
||||
const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000'
|
||||
|
||||
/**
|
||||
* Instance Axios configurée pour l'API Mesh.
|
||||
*/
|
||||
const apiClient: AxiosInstance = axios.create({
|
||||
baseURL: API_BASE_URL,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* Intercepteur pour ajouter le token d'authentification à chaque requête.
|
||||
*/
|
||||
apiClient.interceptors.request.use(
|
||||
(config) => {
|
||||
const token = useAuthStore.getState().token
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`
|
||||
}
|
||||
return config
|
||||
},
|
||||
(error) => Promise.reject(error)
|
||||
)
|
||||
|
||||
/**
|
||||
* Intercepteur pour gérer les erreurs d'authentification.
|
||||
*/
|
||||
apiClient.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error.response?.status === 401) {
|
||||
// Token expiré ou invalide, déconnecter l'utilisateur
|
||||
useAuthStore.getState().logout()
|
||||
window.location.href = '/login'
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
// ==================== Types ====================
|
||||
|
||||
export interface RegisterRequest {
|
||||
username: string
|
||||
password: string
|
||||
email?: string
|
||||
}
|
||||
|
||||
export interface LoginRequest {
|
||||
username: string
|
||||
password: string
|
||||
}
|
||||
|
||||
export interface AuthResponse {
|
||||
access_token: string
|
||||
token_type: string
|
||||
user_id: string
|
||||
username: string
|
||||
}
|
||||
|
||||
export interface User {
|
||||
user_id: string
|
||||
username: string
|
||||
email?: string
|
||||
}
|
||||
|
||||
export interface Room {
|
||||
room_id: string
|
||||
name: string
|
||||
owner_user_id: string
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface RoomMember {
|
||||
user_id: string
|
||||
username: string
|
||||
role: 'owner' | 'member' | 'guest'
|
||||
presence: 'online' | 'busy' | 'offline'
|
||||
}
|
||||
|
||||
export interface CapabilityTokenRequest {
|
||||
room_id: string
|
||||
capabilities: string[]
|
||||
target_peer_id?: string
|
||||
}
|
||||
|
||||
export interface CapabilityTokenResponse {
|
||||
capability_token: string
|
||||
expires_in: number
|
||||
}
|
||||
|
||||
// ==================== API Functions ====================
|
||||
|
||||
/**
|
||||
* Authentification et gestion utilisateur.
|
||||
*/
|
||||
export const authApi = {
|
||||
/**
|
||||
* Enregistrer un nouvel utilisateur.
|
||||
*/
|
||||
register: async (data: RegisterRequest): Promise<AuthResponse> => {
|
||||
const response = await apiClient.post<AuthResponse>('/api/auth/register', data)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* Se connecter.
|
||||
*/
|
||||
login: async (data: LoginRequest): Promise<AuthResponse> => {
|
||||
const response = await apiClient.post<AuthResponse>('/api/auth/login', data)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* Récupérer les informations de l'utilisateur courant.
|
||||
*/
|
||||
getMe: async (): Promise<User> => {
|
||||
const response = await apiClient.get<User>('/api/auth/me')
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* Demander un capability token.
|
||||
*/
|
||||
requestCapability: async (data: CapabilityTokenRequest): Promise<CapabilityTokenResponse> => {
|
||||
const response = await apiClient.post<CapabilityTokenResponse>(
|
||||
'/api/auth/capability',
|
||||
data
|
||||
)
|
||||
return response.data
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Gestion des rooms.
|
||||
*/
|
||||
export const roomsApi = {
|
||||
/**
|
||||
* Créer une nouvelle room.
|
||||
*/
|
||||
create: async (name: string): Promise<Room> => {
|
||||
const response = await apiClient.post<Room>('/api/rooms/', { name })
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* Lister toutes les rooms accessibles.
|
||||
*/
|
||||
list: async (): Promise<Room[]> => {
|
||||
const response = await apiClient.get<Room[]>('/api/rooms/')
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* Récupérer les détails d'une room.
|
||||
*/
|
||||
get: async (roomId: string): Promise<Room> => {
|
||||
const response = await apiClient.get<Room>(`/api/rooms/${roomId}`)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* Récupérer les membres d'une room.
|
||||
*/
|
||||
getMembers: async (roomId: string): Promise<RoomMember[]> => {
|
||||
const response = await apiClient.get<RoomMember[]>(`/api/rooms/${roomId}/members`)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* Ajouter un membre à une room.
|
||||
*/
|
||||
addMember: async (roomId: string, username: string): Promise<RoomMember> => {
|
||||
const response = await apiClient.post<RoomMember>(`/api/rooms/${roomId}/members`, {
|
||||
username,
|
||||
})
|
||||
return response.data
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Gestion des sessions P2P.
|
||||
*/
|
||||
export const p2pApi = {
|
||||
/**
|
||||
* Créer une session P2P.
|
||||
*/
|
||||
createSession: async (data: {
|
||||
room_id: string
|
||||
target_peer_id: string
|
||||
kind: 'file' | 'folder' | 'terminal'
|
||||
capabilities: string[]
|
||||
}) => {
|
||||
const response = await apiClient.post('/api/p2p/session', data)
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* Lister les sessions P2P actives.
|
||||
*/
|
||||
listSessions: async () => {
|
||||
const response = await apiClient.get('/api/p2p/sessions')
|
||||
return response.data
|
||||
},
|
||||
|
||||
/**
|
||||
* Fermer une session P2P.
|
||||
*/
|
||||
closeSession: async (sessionId: string) => {
|
||||
const response = await apiClient.delete(`/api/p2p/session/${sessionId}`)
|
||||
return response.data
|
||||
},
|
||||
}
|
||||
|
||||
export default apiClient
|
||||
Reference in New Issue
Block a user