summaryrefslogtreecommitdiff
path: root/blocks/eda-frontend/src/utils/Api.js
blob: f9302174a63947ea814bf301e8abf426e6436855 (plain)
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Creating a new instance of axios for custom API config.
import axios from 'axios'

const getCookie = (name) => {
  let cookieValue = null

  if (document.cookie && document.cookie !== '') {
    const cookies = document.cookie.split(';')
    for (let i = 0; i < cookies.length; i++) {
      const cookie = cookies[i].trim()

      // Does this cookie string begin with the name we want?
      if (cookie.substring(0, name.length + 1) === (name + '=')) {
        cookieValue = decodeURIComponent(cookie.substring(name.length + 1))

        break
      }
    }
  }

  return cookieValue
}

const csrftoken = getCookie('csrftoken')

const api = axios.create({
  baseURL: '/api/',
  responseType: 'json',
  xsrfCookieName: 'csrftoken',
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json',
    'X-CSRFToken': csrftoken
  },
  withCredentials: true
})

const isSessionExpired = () => {
  const expireAt = localStorage.getItem('expire_at')
  return !expireAt || new Date(expireAt) < new Date()
}

const deleteCookie = (name) => {
  document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'
}

const refreshSession = async () => {
  try {
    const response = await api.get(`simulation/get_session?app_name=${process.env.REACT_APP_NAME}`)
    const sessionId = response.data.session_id
    const expireAt = response.data.expire_at
    localStorage.setItem('session_id', sessionId)
    localStorage.setItem('expire_at', expireAt)
    console.log('Refreshed sessionId', sessionId)
    return sessionId
  } catch (error) {
    console.error('Failed to refresh session', error)
    return null
  }
}

let refreshingSession = null

api.interceptors.request.use(async (config) => {
  // Avoid infinite loop by skipping the interceptor for session refresh requests
  if (config.url.includes('simulation/get_session')) {
    return config
  }

  let sessionId = localStorage.getItem('session_id')

  // Check if session is expired and refresh if necessary
  if (!sessionId || isSessionExpired()) {
    if (!refreshingSession) {
      console.log('Session expired, refreshing...')
      deleteCookie('sessionid')

      refreshingSession = refreshSession().finally(() => {
        refreshingSession = null
      })
    }

    // Refresh session but avoid triggering interceptor again
    sessionId = await refreshingSession
    if (!sessionId) {
      return Promise.reject(new Error('Failed to refresh session'))
    }
  }

  if (sessionId) {
    config.headers['Session-ID'] = sessionId // Custom header for session ID
    console.log('sessionId', sessionId)
  }
  return config
}, (error) => {
  return Promise.reject(error)
})

export default api