All files / src/services api.ts

95.65% Statements 22/23
91.66% Branches 11/12
66.66% Functions 2/3
95.65% Lines 22/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 57 58      25x               25x 52x 52x   52x 1x     52x       25x         6x 4x         4x 4x 1x 1x 1x         3x 2x 2x 2x 1x 1x       4x          
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) => {
    return 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 flow context — force-refresh the
      // JWT once and retry the request before giving up.
      const token = await authStore.getAccessToken()
      if (!token) {
        await authStore.logout()
        window.location.href = '/login'
        return Promise.reject(error)
      }
 
      // Session valid but 401 (likely stale/missing custom:flowId 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