140 lines
4.2 KiB
TypeScript
140 lines
4.2 KiB
TypeScript
import axios from 'axios'
|
||
import { store } from '../store'
|
||
import { jwtDecode } from 'jwt-decode'
|
||
import appConfig from '../proxy/configs/app.config'
|
||
import { refreshToken } from './auth.service'
|
||
import { isLoginSuccess } from '../proxy/account/models'
|
||
|
||
const unauthorizedCode = [401]
|
||
|
||
const platformApiService = axios.create({
|
||
timeout: 60000,
|
||
baseURL: appConfig.baseUrl,
|
||
})
|
||
|
||
platformApiService.interceptors.request.use(
|
||
async (config) => {
|
||
const { auth } = store.getState()
|
||
|
||
if (auth.session.token) {
|
||
config.headers['Authorization'] = `Bearer ${auth.session.token}`
|
||
}
|
||
|
||
return config
|
||
},
|
||
(error) => Promise.reject(error),
|
||
)
|
||
|
||
platformApiService.interceptors.request.use(async (config) => {
|
||
const state = store.getState()
|
||
const cultureName =
|
||
state.locale.currentLang ?? state.abpConfig?.config?.localization?.currentCulture?.cultureName
|
||
|
||
if (!config.headers['Accept-Language'] && cultureName) {
|
||
config.headers['Accept-Language'] = cultureName
|
||
}
|
||
|
||
const { currentTenantName } = state.locale
|
||
if (currentTenantName) {
|
||
config.headers['__tenant'] = currentTenantName
|
||
} else {
|
||
config.headers.delete('__tenant')
|
||
}
|
||
|
||
return config
|
||
})
|
||
|
||
platformApiService.interceptors.response.use(
|
||
(response) => response,
|
||
async (error) => {
|
||
// Geçersiz tenant seçilmişse Host olarak tekrar bağlan.
|
||
// __tenant header'ı gönderilmiş bir isteğe 404 geliyorsa tenant bulunamadı demektir.
|
||
const hasTenantHeader = !!error.config?.headers?.['__tenant']
|
||
const responseText = JSON.stringify(error.response?.data ?? '').toLowerCase()
|
||
|
||
const isTenantNotFound =
|
||
error.response?.status === 404 &&
|
||
hasTenantHeader &&
|
||
responseText.includes('tenant')
|
||
|
||
if (isTenantNotFound && !error.config._tenantRetried) {
|
||
store.getActions().locale.setTenantName(undefined)
|
||
error.config._tenantRetried = true
|
||
error.config.headers.delete('__tenant')
|
||
error.silent = true
|
||
return platformApiService.request(error.config)
|
||
}
|
||
|
||
if (unauthorizedCode.includes(error.response?.status)) {
|
||
const { signIn, signOut, setIsRefreshing } = store.getActions().auth
|
||
const { auth } = store.getState()
|
||
if (auth.isRefreshing) {
|
||
error.silent = true
|
||
return Promise.reject(error)
|
||
}
|
||
setIsRefreshing(true)
|
||
try {
|
||
const resp = await refreshToken(auth.session.refreshToken)
|
||
|
||
if (resp.status === 200 && isLoginSuccess(resp.data)) {
|
||
const { access_token, refresh_token, expires_in } = resp.data
|
||
// TODO: Add token type
|
||
const tokenDetails = jwtDecode<any>(access_token)
|
||
signIn({
|
||
session: {
|
||
token: access_token,
|
||
refreshToken: refresh_token,
|
||
expiresIn: expires_in,
|
||
expire: tokenDetails?.exp,
|
||
signedIn: true,
|
||
},
|
||
user: {
|
||
id: tokenDetails?.sub,
|
||
userName: tokenDetails?.preferred_username,
|
||
email: tokenDetails?.email,
|
||
authority: [tokenDetails?.role],
|
||
name: `${tokenDetails?.given_name} ${tokenDetails?.family_name}`.trim(),
|
||
role: 'teacher',
|
||
},
|
||
})
|
||
setIsRefreshing(false)
|
||
// Retry the original request with new token
|
||
error.config.headers['Authorization'] = `Bearer ${access_token}`
|
||
return axios.request(error.config)
|
||
} else {
|
||
setIsRefreshing(false)
|
||
signOut()
|
||
error.silent = true
|
||
}
|
||
} catch (error2) {
|
||
setIsRefreshing(false)
|
||
signOut()
|
||
error.silent = true
|
||
}
|
||
}
|
||
|
||
return Promise.reject(error)
|
||
},
|
||
)
|
||
|
||
platformApiService.interceptors.response.use(
|
||
(response) => response,
|
||
async (error) => {
|
||
console.log('Error interceptor')
|
||
console.error(error)
|
||
if (!error.silent) {
|
||
const { messages } = store.getActions().base
|
||
messages.addError({
|
||
id: crypto.randomUUID(),
|
||
message: error.response?.data?.error?.message ?? error.message ?? 'Bir hata oluştu',
|
||
title: 'Hata!',
|
||
cid: error.response?.headers['x-correlation-id'],
|
||
statusCode: error.response?.status?.toString() ?? error.code,
|
||
})
|
||
}
|
||
|
||
return Promise.reject(error)
|
||
},
|
||
)
|
||
|
||
export default platformApiService
|