mirror of
https://github.com/beak-insights/felicity-lims.git
synced 2025-02-21 07:22:53 +08:00
134 lines
3.6 KiB
TypeScript
134 lines
3.6 KiB
TypeScript
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
import { getAuthData } from '@/auth';
|
|
import { REST_BASE_URL, GQL_BASE_URL, STORAGE_AUTH_KEY } from '@/conf';
|
|
|
|
// Define TypeScript interfaces for better type safety
|
|
interface AuthData {
|
|
auth?: {
|
|
token?: string;
|
|
refresh?: string;
|
|
};
|
|
}
|
|
|
|
interface RefreshTokenResponse {
|
|
data: {
|
|
refresh: {
|
|
token: string;
|
|
tokenType: string;
|
|
user: {
|
|
uid: string;
|
|
firstName: string;
|
|
lastName: string;
|
|
groups: Array<{
|
|
uid: string;
|
|
name: string;
|
|
keyword: string;
|
|
pages: string[];
|
|
permissions: Array<{
|
|
uid: string;
|
|
action: string;
|
|
target: string;
|
|
}>;
|
|
}>;
|
|
preference: {
|
|
uid: string;
|
|
expandedMenu: boolean;
|
|
theme: string;
|
|
departments: Array<{
|
|
uid: string;
|
|
name: string;
|
|
}>;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
}
|
|
|
|
const axiosInstance: AxiosInstance = axios.create({
|
|
baseURL: `${REST_BASE_URL}/api/v1/`,
|
|
timeout: 5000,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Access-Control-Allow-Origin': '*',
|
|
'Access-Control-Allow-Methods': 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
|
|
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization',
|
|
},
|
|
});
|
|
|
|
// Request Interceptor
|
|
axiosInstance.interceptors.request.use(
|
|
(config: AxiosRequestConfig) => {
|
|
const authData: AuthData = getAuthData();
|
|
if (authData?.auth?.token && config.headers) {
|
|
config.headers['Authorization'] = `Bearer ${authData.auth.token}`;
|
|
}
|
|
return config;
|
|
},
|
|
(error) => Promise.reject(error)
|
|
);
|
|
|
|
// Response Interceptor
|
|
axiosInstance.interceptors.response.use(
|
|
(res: AxiosResponse) => res,
|
|
async (err) => {
|
|
const originalConfig = err.config;
|
|
if (err.response && err.response.status === 401 && !originalConfig._retry) {
|
|
originalConfig._retry = true;
|
|
try {
|
|
const authData: AuthData = getAuthData();
|
|
const response: RefreshTokenResponse = await axiosInstance.post(
|
|
'',
|
|
{
|
|
query: `
|
|
mutation refresh($refreshToken: String!) {
|
|
refresh(refreshToken: $refreshToken) {
|
|
token
|
|
tokenType
|
|
user {
|
|
uid
|
|
firstName
|
|
lastName
|
|
groups {
|
|
permissions {
|
|
uid
|
|
action
|
|
target
|
|
}
|
|
uid
|
|
name
|
|
keyword
|
|
pages
|
|
}
|
|
preference {
|
|
uid
|
|
expandedMenu
|
|
theme
|
|
departments {
|
|
uid
|
|
name
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`,
|
|
variables: { refreshToken: authData?.auth?.refresh }
|
|
},
|
|
{
|
|
baseURL: GQL_BASE_URL
|
|
}
|
|
);
|
|
|
|
// Update localStorage with new auth data
|
|
localStorage.setItem(STORAGE_AUTH_KEY, JSON.stringify(response.data.refresh));
|
|
|
|
// Retry the original request with new token
|
|
return axiosInstance(originalConfig);
|
|
} catch (_error) {
|
|
return Promise.reject(_error);
|
|
}
|
|
}
|
|
return Promise.reject(err);
|
|
}
|
|
);
|
|
export default axiosInstance;
|