2026-02-24 20:44:16 +00:00
|
|
|
|
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) => {
|
2026-03-10 13:42:16 +00:00
|
|
|
|
// 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)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-24 20:44:16 +00:00
|
|
|
|
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
|