mirror of https://github.com/nocodb/nocodb
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.
108 lines
3.3 KiB
108 lines
3.3 KiB
import type { Api } from 'nocodb-sdk' |
|
const DbNotFoundMsg = 'Database config not found' |
|
|
|
const TIMEOUT_RETRY_COUNT = 1 |
|
|
|
export function addAxiosInterceptors(api: Api<any>) { |
|
const state = useGlobal() |
|
const router = useRouter() |
|
const route = router.currentRoute |
|
const optimisedQuery = useState('optimisedQuery', () => true) |
|
|
|
const axiosInstance = api.instance |
|
|
|
axiosInstance.interceptors.request.use((config) => { |
|
config.headers['xc-gui'] = 'true' |
|
|
|
if (state.token.value && !config.headers['xc-short-token']) { |
|
config.headers['xc-auth'] = state.token.value |
|
} |
|
|
|
if (!config.url?.endsWith('/user/me') && !config.url?.endsWith('/admin/roles') && state.previewAs?.value) { |
|
config.headers['xc-preview'] = state.previewAs.value |
|
} |
|
|
|
if (!config.url?.endsWith('/user/me') && !config.url?.endsWith('/admin/roles')) { |
|
if (route.value && route.value.params && route.value.params.typeOrId === 'base') { |
|
config.headers['xc-shared-base-id'] = route.value.params.baseId |
|
delete config.headers['xc-auth'] |
|
} else if (route.value && route.value.params && route.value.params.typeOrId === 'ERD') { |
|
config.headers['xc-shared-erd-id'] = route.value.params.erdUuid |
|
delete config.headers['xc-auth'] |
|
} |
|
} |
|
|
|
if (!optimisedQuery.value) { |
|
config.params = { ...(config.params ?? {}), opt: 'false' } |
|
} |
|
|
|
return config |
|
}) |
|
|
|
axiosInstance.interceptors.response.use( |
|
(response) => response, |
|
async (error) => { |
|
const isSharedPage = |
|
route.value?.params?.typeOrId === 'base' || route.value?.params?.typeOrId === 'ERD' || route.value.meta.public |
|
|
|
if (error.code === 'ERR_CANCELED') return Promise.reject(error) |
|
|
|
if (error.response?.data?.msg === DbNotFoundMsg) { |
|
return router.replace('/base/0') |
|
} |
|
|
|
if (!error.response || error.response.status !== 401) { |
|
return Promise.reject(error) |
|
} |
|
|
|
if (error.config.url === '/auth/token/refresh') { |
|
await state.signOut({ |
|
redirectToSignin: !route.value.meta.public, |
|
skipApiCall: true, |
|
}) |
|
return Promise.reject(error) |
|
} |
|
|
|
let retry = 0 |
|
do { |
|
try { |
|
const token = await state.refreshToken({ |
|
axiosInstance, |
|
skipLogout: true, |
|
}) |
|
|
|
if (!token) { |
|
await state.signOut({ |
|
redirectToSignin: !isSharedPage, |
|
skipApiCall: true, |
|
}) |
|
return Promise.reject(error) |
|
} |
|
|
|
const config = error.config |
|
config.headers['xc-auth'] = token |
|
|
|
const response = await axiosInstance.request(config) |
|
return response |
|
} catch (refreshTokenError) { |
|
if ((refreshTokenError as any)?.code === 'ERR_CANCELED') { |
|
return Promise.reject(refreshTokenError) |
|
} |
|
|
|
// if shared execution error, don't sign out |
|
if (!(refreshTokenError instanceof SharedExecutionError)) { |
|
await state.signOut({ |
|
redirectToSignin: !isSharedPage, |
|
skipApiCall: true, |
|
}) |
|
return Promise.reject(error) |
|
} |
|
|
|
if (retry >= TIMEOUT_RETRY_COUNT) return Promise.reject(error) |
|
} |
|
} while (retry++ < TIMEOUT_RETRY_COUNT) |
|
}, |
|
) |
|
|
|
return api |
|
}
|
|
|