All files / src/services api.ts

69.56% Statements 16/23
50% Branches 6/12
66.66% Functions 2/3
69.56% Lines 16/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56      18x               18x 11x 11x   11x 1x     11x       18x     3x 1x         1x 1x 1x 1x 1x                           2x          
import axios from 'axios'
import { useAuthStore } from '@/stores/auth'
 
const api = axios.create({
  baseURL: import.meta.env.VITE_API_URL || 'https://api.flows.browsway.com',
  headers: {
    'Content-Type': 'application/json'
  }
})
 
// Add auth token to every request
api.interceptors.request.use(async (config) => {
  const authStore = useAuthStore()
  const token = await authStore.getAccessToken()
 
  if (token) {
    config.headers.Authorization = `Bearer ${token}`
  }
 
  return config
})
 
// Handle auth errors
api.interceptors.response.use(
  (response) => response,
  async (error) => {
    if (error.response?.status === 401) {
      const authStore = useAuthStore()
      // Only logout if the session is truly expired (no valid token obtainable).
      // If getAccessToken() returns a token, the session is still valid and the
      // 401 came from a missing / invalid tenant context — force-refresh the
      // JWT once and retry the request before giving up.
      const token = await authStore.getAccessToken()
      Eif (!token) {
        await authStore.logout()
        window.location.href = '/login'
        return Promise.reject(error)
      }
 
      // Session valid but 401 (likely stale/missing custom:tenantId in JWT).
      // Force-refresh the token once and retry the original request.
      if (!error.config._retried) {
        error.config._retried = true
        const refreshedToken = await authStore.getAccessToken(true)
        if (refreshedToken) {
          error.config.headers['Authorization'] = `Bearer ${refreshedToken}`
          return api(error.config)
        }
      }
    }
    return Promise.reject(error)
  }
)
 
export default api