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.
Mobile/api/services/abstract.service.tsx

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;
}
}
}