diff --git a/web/src/store/index.js b/web/src/store/index.js index 0b1a34c..64cf382 100644 --- a/web/src/store/index.js +++ b/web/src/store/index.js @@ -11,6 +11,18 @@ Vue.use(Vuex); const axios = AxiosBootstrap.create({ baseURL: '/api', }); +axios.interceptors.response.use(response => response, error => { + if (error.response.status === 401) { + console.log('401 interceptor fired'); + store.dispatch('reloadToken').then((ok) => { + if (ok) { + error.config.headers['Authorization'] = `Token ${store.state.token}`; + return axios.request(error.config); + } + }); + } else + return Promise.reject(error); +}); axios.interceptors.response.use(response => response, error => { console.log('error interceptor fired'); @@ -46,10 +58,11 @@ const store = new Vuex.Store({ tickets: [], userRoles: ['admin', 'team', 'orga', 'user'], lastEvent: localStorage.getItem('lf_lastEvent') || '36C3', - lastUsed: localStorage.getItem('lf_lastUsed') || {}, + lastUsed: JSON.parse(localStorage.getItem('lf_lastUsed') || '{}'), remember: false, user: null, token: null, + token_expiry: null, local_loaded: false, }, getters: { @@ -63,6 +76,7 @@ const store = new Vuex.Store({ state.remember = localStorage.getItem('remember') === 'true' state.user = localStorage.getItem('user') state.token = localStorage.getItem('token') + state.token_expiry = localStorage.getItem('token_expiry') state.local_loaded = true } @@ -72,7 +86,7 @@ const store = new Vuex.Store({ mutations: { updateLastUsed(state, diff) { state.lastUsed = _.extend(state.lastUsed, diff); - localStorage.setItem('lf_lastUsed', state.lastUsed); + localStorage.setItem('lf_lastUsed', JSON.stringify(state.lastUsed)); }, updateLastEvent(state, slug) { state.lastEvent = slug; @@ -125,17 +139,22 @@ const store = new Vuex.Store({ }, setUser(state, user) { state.user = user; - localStorage.setItem('user', user); + if (user) + localStorage.setItem('user', user); }, - setToken(state, token) { + setToken(state, {token, expiry}) { state.token = token; - localStorage.setItem('token', token); + state.token_expiry = expiry; + if (token) + localStorage.setItem('token', token); + localStorage.setItem('token_expiry', expiry); }, logout(state) { state.user = null; state.token = null; localStorage.removeItem('user'); localStorage.removeItem('token'); + localStorage.removeItem('token_expiry'); router.push('/login'); }, }, @@ -150,9 +169,10 @@ const store = new Vuex.Store({ credentials: 'omit' }).then(r => r.json()) if (data.token) { - commit('setToken', data.token); + commit('setToken', data); commit('setUser', username); axios.defaults.headers.common['Authorization'] = `Token ${data.token}`; + dispatch('afterLogin'); return true; } else { return false; @@ -162,6 +182,31 @@ const store = new Vuex.Store({ return false; } }, + async reloadToken({commit, state}) { + try { + const data = await fetch('/api/2/login/', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({username: state.user, password: state.token}), + credentials: 'omit' + }).then(r => r.json()) + if (data.token) { + commit('setToken', data); + axios.defaults.headers.common['Authorization'] = `Token ${data.token}`; + return true; + } + } catch (e) { + console.error(e); + } + //credentials failed, logout + store.commit('logout'); + router.push('/login'); + }, + async afterLogin() { + await store.dispatch('loadBoxes'); + await store.dispatch('loadEventItems'); + await store.dispatch('loadTickets'); + }, async loadEvents({commit}) { const {data} = await axios.get('/2/events/'); commit('replaceEvents', data); @@ -224,7 +269,6 @@ export default store; store.dispatch('loadEvents').then(() => { if (store.getters.isLoggedIn) { axios.defaults.headers.common['Authorization'] = `Token ${store.state.token}`; - store.dispatch('loadEventItems'); - store.dispatch('loadBoxes'); + store.dispatch('afterLogin'); } });