You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
53 lines
1.4 KiB
53 lines
1.4 KiB
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
import apiClient from "../client";
|
|
import { AUTH } from "../endpoints";
|
|
|
|
const ACCESS_TOKEN_PATH = "access-token";
|
|
const REFRESH_TOKEN_PATH = "refresh-token";
|
|
|
|
export abstract class AbstractService {
|
|
protected async request<T>(callback: () => Promise<T>): Promise<T> {
|
|
try {
|
|
return await callback();
|
|
} catch (error: any) {
|
|
if (error.response?.status === 401) {
|
|
const success = await this.tryRefreshToken();
|
|
if (success) {
|
|
return await callback();
|
|
} else {
|
|
throw new Error("Session expired");
|
|
}
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
private async tryRefreshToken(): Promise<boolean> {
|
|
try {
|
|
const refreshToken = await AsyncStorage.getItem(REFRESH_TOKEN_PATH);
|
|
|
|
if (!refreshToken) return false;
|
|
|
|
const response = await apiClient.post(AUTH.REFRESH_TOKEN, {
|
|
refreshToken,
|
|
});
|
|
|
|
const { accessToken, refreshToken: newRefreshToken } = response.data;
|
|
|
|
// Save new tokens
|
|
await AsyncStorage.setItem(ACCESS_TOKEN_PATH, accessToken);
|
|
await AsyncStorage.setItem("refreshToken", newRefreshToken);
|
|
|
|
// Update apiClient headers
|
|
apiClient.defaults.headers.common[
|
|
"Authorization"
|
|
] = `Bearer ${accessToken}`;
|
|
|
|
return true;
|
|
} catch (e) {
|
|
console.error("Refresh token failed", e);
|
|
return false;
|
|
}
|
|
}
|
|
}
|