Files
matrix-frontend/src/services/RestService.ts
T
2025-09-13 12:12:23 +02:00

170 lines
5.1 KiB
TypeScript

import axios, {AxiosInstance, Method} from 'axios';
import {makeRedirectUri} from "expo-auth-session";
import {SpotifyConfig, User} from "@/src/model/User";
import {Platform} from "react-native";
const API_URL = process.env.EXPO_PUBLIC_API_URL;
export interface Token {
access_token: string;
refresh_token: string;
expires_in: number;
token_type: string;
scope: string;
}
export interface ApiResponse<T> {
ok: boolean;
data: T;
}
class RestService {
private readonly jwtToken: string | null;
private api: AxiosInstance;
constructor(jwtToken: string | null) {
this.jwtToken = jwtToken;
this.api = axios.create({
baseURL: API_URL,
timeout: 10000, // Set a timeout for requests
withCredentials: Platform.OS === 'web',
});
this.api.interceptors.request.use(
(config) => {
if (this.jwtToken) {
config.headers.Authorization = `Bearer ${this.jwtToken}`;
}
console.log('Request Config:', config);
return config;
},
(error) => {
console.error('Request Error:', error);
return Promise.reject(error);
}
);
this.api.interceptors.response.use(
(response) => {
console.log('Response Data:', response.data);
return response;
},
(error) => {
console.error('Response Error:', error.response?.data || error.message);
return Promise.reject(error);
}
);
}
async exchangeSpotifyCodeForToken(code: string): Promise<ApiResponse<{ token: Token }>> {
const redirectUri = makeRedirectUri({
scheme: 'led.matrix',
path: 'callback',
});
return this.request<ApiResponse<{ token: Token }>>(
'POST',
`/spotify/token/generate`,
{"authCode": code, "redirectUri": redirectUri},
{'Content-Type': 'application/json'}
);
}
async fetchAllUser(): Promise<ApiResponse<{ users: User[] }>> {
return this.request<ApiResponse<{ users: User[] }>>('GET', '/user');
}
async fetchUserById(id: string): Promise<ApiResponse<User>> {
return this.request<ApiResponse<User>>('GET', `/user/${id}`);
}
async getSelf(): Promise<ApiResponse<User>> {
return this.request<ApiResponse<User>>('GET', '/user/me');
}
async changeSelfPassword(password: string, passwordConfirmation: string): Promise<ApiResponse<{
message: string
}>> {
return this.request<ApiResponse<{ message: string }>>(
'PUT',
'/user/me/password',
{password, passwordConfirmation},
{'Content-Type': 'application/json'}
);
}
async sendPayloadToSocket(userId: string, payload: object): Promise<any> {
return this.request(
'POST',
'/websocket/send-message',
{users: [userId], payload},
{'Content-Type': 'application/json'}
);
}
async broadcast(payload: object): Promise<any> {
return this.request(
'POST',
'/websocket/broadcast',
{payload},
{'Content-Type': 'application/json'}
);
}
async updateSelfSpotifyConfig(spotifyConfig?: SpotifyConfig): Promise<ApiResponse<{ message: string }>> {
const payload = spotifyConfig ?? {};
return this.request<ApiResponse<{ message: string }>>(
'PUT',
'/user/me/spotify',
payload,
{'Content-Type': 'application/json'}
);
}
async removeSpotifyConfig(): Promise<ApiResponse<User>> {
return this.request<ApiResponse<User>>('DELETE', '/user/me/spotify');
}
async login(username: string, password: string): Promise<ApiResponse<{
message?: string, token?: string, details?: {
field: string;
code: string;
}
}>> {
return this.request<ApiResponse<{
message?: string, token?: string, details?: {
field: string;
code: string;
}
}>>(
"POST",
'/auth/login',
{username, password},
{'Content-Type': 'application/json'}
);
}
async logout(): Promise<ApiResponse<{ message: string }>> {
return this.request<ApiResponse<{ message: string }>>('POST', '/auth/logout');
}
private async request<T>(method: Method, url: string, data?: any, headers?: any): Promise<T> {
try {
const response = await this.api.request<T>({
method,
url,
data,
headers,
validateStatus: (status) => status >= 200 && status < 500,
}
);
return response.data;
} catch (error) {
console.error('Error during request:', error);
throw error;
}
}
}
export {RestService};