refactor RestService.ts

This commit is contained in:
StarAppeal
2024-12-11 09:14:16 +01:00
parent ab0d1b694f
commit 21b5bf34be
5 changed files with 130 additions and 172 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ export default function SettingsScreen() {
expirationDate: new Date(Date.now() + token.expires_in * 1000),
};
RestService.updateSelfSpotifyConfig(spotifyConfig, jwtToken!).then((result) => {
new RestService(jwtToken).updateSelfSpotifyConfig(spotifyConfig).then((result) => {
console.log("Spotify Token gespeichert");
console.log(result);
});
+3 -4
View File
@@ -2,8 +2,7 @@ import React, {useState} from "react";
import {Button, Paragraph} from "react-native-paper";
import ThemedTextInput from "@/src/components/themed/ThemedTextInput";
import {useTheme} from "@/src/context/ThemeProvider";
import Modal from "react-native-modal";
import {StyleSheet, View} from "react-native";
import {StyleSheet, View, Modal} from "react-native";
import {RestService} from "@/src/services/RestService";
import {useAuth} from "@/src/context/AuthProvider";
@@ -24,7 +23,7 @@ export default function ChangePasswordModal() {
setApiResponse({success: false, message: "Passwörter stimmen nicht überein!"});
return;
}
RestService.changeSelfPassword(password, confirmPassword, jwtToken!).then(
new RestService(jwtToken).changeSelfPassword(password, confirmPassword).then(
(response) => {
setApiResponse(response);
if (response.success) {
@@ -50,7 +49,7 @@ export default function ChangePasswordModal() {
<Button mode="outlined" onPress={() => setIsVisible(true)}>
Passwort ändern
</Button>
<Modal isVisible={isVisible} onBackdropPress={resetModal}>
<Modal visible={isVisible} onDismiss={resetModal} animationType={"slide"} transparent={true}>
<View style={styles.modalContent}>
<Paragraph>Passwort ändern</Paragraph>
{apiResponse && apiResponse.message && (
+2 -2
View File
@@ -44,7 +44,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({children}
}, []);
const saveUser = async (token: string) => {
const user = await RestService.getSelf(token);
const user = await new RestService(token).getSelf();
if (!user) {
// token is invalid
await removeFromStorage(JWT_TOKEN_KEY);
@@ -64,7 +64,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({children}
console.log("Already authenticated");
return;
}
const response = await RestService.login(username, password);
const response = await new RestService(null).login(username, password);
if (!response.success) {
console.error("Login failed:", response.message);
setError({
+1 -1
View File
@@ -35,7 +35,7 @@ export const useSpotifyAuth = (
if (response?.type === 'success') {
try {
const {code} = response.params;
const token = (await RestService.exchangeSpotifyCodeForToken(code,jwtToken));
const token = (await new RestService(jwtToken).exchangeSpotifyCodeForToken(code));
console.log('Token:', token);
onAuthSuccess(token);
} catch (error) {
+123 -164
View File
@@ -1,178 +1,137 @@
import axios from 'axios';
import axios, {AxiosInstance, Method} from 'axios';
import {makeRedirectUri} from "expo-auth-session";
import {SpotifyConfig, User} from "@/src/model/User";
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,
access_token: string;
refresh_token: string;
expires_in: number;
token_type: string;
scope: string;
}
const RestService = {
exchangeSpotifyCodeForToken: async (code: string, jwtToken: string) => {
try {
const redirectUri = makeRedirectUri({
scheme: 'led.matrix',
path: 'callback',
});
const response = await axios.get<{ token: Token }>(
`${API_URL}/spotify/token/generate/code/${code}/redirect-uri/${encodeURIComponent(redirectUri)}`, {
headers: {
Authorization: `Bearer ${jwtToken}`,
}
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
});
this.api.interceptors.request.use(
(config) => {
if (this.jwtToken) {
config.headers.Authorization = `Bearer ${this.jwtToken}`;
}
);
return response.data.token;
} catch (error) {
console.error("Error exchanging Spotify code:", error);
throw error;
}
},
fetchAllUser: async (jwtToken: string) => {
try {
const response = await axios.get<{ users: User[] }>(`${API_URL}/user`, {
headers: {
Authorization: `Bearer ${jwtToken}`,
},
});
return response.data;
} catch (error) {
console.error("Error fetching users:", error);
throw error;
}
},
fetchUserById: async (id: string, jwtToken: string) => {
try {
const response = await axios.get<User>(`${API_URL}/user/${id}`, {
headers: {
Authorization: `Bearer ${jwtToken}`,
},
});
return response.data;
} catch (error) {
console.error("Error fetching user by id:", error);
throw error;
}
},
getSelf: async (jwtToken: string) => {
try {
const response = await axios.get<User>(`${API_URL}/user/me`, {
headers: {
Authorization: `Bearer ${jwtToken}`,
},
});
return response.data;
} catch (error) {
console.error("Error fetching self:", error);
throw error;
}
},
changeSelfPassword: async (
password: string,
passwordConfirmation: string,
jwtToken: string
) => {
try {
const response = await axios.put<{ result: { success: boolean; message: string } }>(
`${API_URL}/user/me/password`,
{password, passwordConfirmation},
{
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
validateStatus: (status) => status >= 200 && status < 500, // Erlaube 4xx-Statuscodes
}
);
return response.data.result;
} catch (error) {
console.error('Unexpected error:', error);
return {success: false, message: 'An unexpected error occurred.'};
}
},
sendPayloadToSocket: async (userId: string, payload: object, jwtToken: string) => {
try {
const response = await axios.post(
`${API_URL}/websocket/send-message`,
{users: [userId], payload},
{
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
}
);
return response.data;
} catch (error) {
console.error("Error sending payload to socket:", error);
throw error;
}
},
broadcast: async (payload: object, jwtToken: String) => {
try {
const response = await axios.post(
`${API_URL}/websocket/broadcast`,
{payload},
{
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
}
);
return response.data;
} catch (error) {
console.error("Error broadcasting payload:", error);
throw error;
}
},
updateSelfSpotifyConfig: async (spotifyConfig: SpotifyConfig, jwtToken: string) => {
try {
const response = await axios.put<{ result: { success: boolean, message: string } }>(
`${API_URL}/user/me/spotify`,
spotifyConfig,
{
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
}
);
return response.data;
} catch (error) {
console.error("Error updating self:", error);
throw error;
}
},
login: async (username: string, password: string) => {
const response = await axios.post<{
success: boolean, token: string, message: string,
id: "username" | "password"
}>(
`${API_URL}/auth/login`, {
username,
password,
}, {
validateStatus: (status) => status === 200 || status === 401 || status === 404,
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);
}
);
return response.data;
}
};
async exchangeSpotifyCodeForToken(code: string): Promise<Token> {
const redirectUri = makeRedirectUri({
scheme: 'led.matrix',
path: 'callback',
});
return this.request<Token>(
'GET',
`/spotify/token/generate/code/${code}/redirect-uri/${encodeURIComponent(redirectUri)}`
);
}
async fetchAllUser(): Promise<{ users: User[] }> {
return this.request<{ users: User[] }>('GET', '/user');
}
async fetchUserById(id: string): Promise<User> {
return this.request<User>('GET', `/user/${id}`);
}
async getSelf(): Promise<User> {
return this.request<User>('GET', '/user/me');
}
async changeSelfPassword(password: string, passwordConfirmation: string): Promise<{ success: boolean; message: string }> {
return this.request<{ success: boolean; 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<{ success: boolean; message: string }> {
return this.request<{ success: boolean; message: string }>(
'PUT',
'/user/me/spotify',
spotifyConfig,
{'Content-Type': 'application/json'}
);
}
async login(username: string, password: string): Promise<{ success: boolean; token: string; message: string; id: "username" | "password" }> {
return this.request<{ success: boolean; token: string; message: string; id: "username" | "password" }>(
"POST",
'/auth/login',
{username, password},
{'Content-Type': 'application/json'}
);
}
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,
});
return response.data;
} catch (error) {
console.error('Error during request:', error);
throw error;
}
}
}
export {RestService};