多维表格
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

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
}