import Vue from 'vue'; import Vuex from 'vuex'; import VueRouter from 'vue-router'; import Axios from 'axios'; import JwtDecode from 'jwt-decode'; import App from './app.vue'; import Dashboard from './components/dashboard.vue'; import LoginForm from './components/forms/login.vue'; import Logout from './components/logout.vue'; import Userlist from './components/userlist.vue'; Vue.use(VueRouter); Vue.use(Vuex); const routes = [ { path: '/login', component: LoginForm }, { path: '/', component: Dashboard }, { path: '/userlist', component: Userlist }, { path: '/logout', component: Logout } ]; const router = new VueRouter({ routes }); const store = new Vuex.Store({ state: { api: {}, navigation: [], persist: { login: {}, authToken: '', jwt: {}, credentials: {} } }, mutations: { setAPI(state, payload) { state.api = payload; }, setNavigation(state, payload) { for (var i = 0; i < payload.length; i++) { state.navigation.push(payload[i]); // = payload; } }, setCredentials(state, payload) { state.persist.credentials = { username: payload.username, password: payload.password }; objectToPersist(state.persist, 'persistantStore'); }, setLogin(state, payload) { state.persist.login = payload.User; state.persist.authToken = payload.AuthToken; state.persist.jwt = JwtDecode(payload.AuthToken); objectToPersist(state.persist, 'persistantStore'); }, clearLogin(state) { state.persist.login = {}; state.persist.authToken = ''; state.persist.jwt = {}; state.persist.credentials = {}; objectToPersist(state.persist, 'persistantStore'); } }, actions: { apiRequest(context, payload) { let doRequest = () => { return new Promise((resolve, reject) => { Axios({ method: payload.method ? payload.method : 'get', baseURL: context.state.api.baseURL, url: payload.endpoint, params: payload.params, data: payload.data, headers: { 'X-Auth-Token': context.state.persist.authToken } }) .then(response => { console.log(response); resolve(response.data); }) .catch(error => { console.dir(error); reject(error); }) }); }; if (payload.endpoint != 'login') { // no jwt check for login call // empty username = not logged in if (!context.state.persist.credentials.username) { return new Promise((resolve, reject) => { // show login page router.push('/login'); reject(['not logged in']); }); } let now = Math.round(Date.now() / 1000); if (context.state.persist.jwt.exp < (now + 300)) { // too old jwt, logout return new Promise((resolve, reject) => { context.commit('clearLogin'); router.push('/login'); reject(['jwt too old, logout']); }); } if ((context.state.persist.jwt.exp - 60) < now) { // jwt near expire, get new one console.log("getting new jwt"); return context.dispatch('login', context.state.persist.credentials) .then(() => { console.log("LOOOGIIIINNN"); return doRequest(); }) .catch(error => { throw error; }) } } return doRequest(); }, login(context, payload) { return new Promise((resolve, reject) => { context.dispatch('apiRequest', { method: 'post', endpoint: 'login', data: payload }) .then(data => { context.commit('setCredentials', payload); context.commit('setLogin', data); resolve(data.User); }) .catch(error => { if (error.response && error.response.data && error.response.data.error) { reject(error.response.data.error); } else { reject([]); } }); }); } } }); function objectToPersist(obj, key) { try { const serialized = JSON.stringify(obj); localStorage.setItem(key ? key : 'persistant', serialized); } catch (error) { console.error(error); } }; function persistToObject(key) { try { const serialized = localStorage.getItem(key ? key : 'persistant'); if (serialized === null) { return undefined; } return JSON.parse(serialized); } catch (error) { console.log(error); return undefined; } } // get store persist part from localStorage let persist = persistToObject('persistantStore'); if (persist) { store.state.persist = persist; } // load init Axios.get('conf/init.json') .then(results => { // set navigation if (!Array.isArray(results.data.navigation)) { alert('invalid data in init.json'); return; } store.commit("setNavigation", results.data.navigation); // set api config in store store.commit("setAPI", results.data.api); // load app, when init finishs new Vue({ el: '#vue-app', components: { App }, data: { navItems: store.state.navigation }, router, store }); }) .catch(error => { alert('error loading: ' + error.message); });