sozsoft-platform/ui/src/services/platformApi.service.ts

141 lines
4.2 KiB
TypeScript
Raw Normal View History

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