logout handling
This commit is contained in:
parent
2ef22fd197
commit
cd7a727f0f
@ -17,6 +17,11 @@
|
||||
"name": "Userlist",
|
||||
"to": "/userlist",
|
||||
"icon": "fa-news"
|
||||
},
|
||||
{
|
||||
"name": "Logout",
|
||||
"to": "/logout",
|
||||
"icon": "fa-lock"
|
||||
}
|
||||
]
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
"description": "JS UI for Basispanel Server Management",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"serve": "WEBPACK_ENV=dev webpack-dev-server --inline --hot --open",
|
||||
"serve": "WEBPACK_ENV=dev webpack-dev-server --inline --hot --host 0.0.0.0",
|
||||
"dev": "WEBPACK_ENV=dev webpack --progress --colors --watch",
|
||||
"build": "WEBPACK_ENV=production webpack --colors"
|
||||
},
|
||||
|
17
src/components/logout.vue
Normal file
17
src/components/logout.vue
Normal file
@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
Sie werden ausgeloggt....
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'logout',
|
||||
created() {
|
||||
this.$store.commit('clearLogin');
|
||||
setTimeout(() => {
|
||||
this.$router.replace('/login');
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
</script>
|
@ -2,15 +2,19 @@
|
||||
|
||||
<div class="My-Table">
|
||||
<table>
|
||||
<tr>
|
||||
<th v-for="(c, i) in columns" :key="i">{{ c.heading }}</th>
|
||||
</tr>
|
||||
<tr v-for="(r, ri) in rows" :key="ri">
|
||||
<td v-for="(c, ci) in columns" :key="ci">
|
||||
<span v-if="c.prop">{{ r[c.prop] }}</span>
|
||||
<span v-else-if="c.render">{{ c.render(r) }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-for="(c, i) in columns" :key="i">{{ c.heading }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody is="transition-group" name="list">
|
||||
<tr v-for="(r, ri) in rows" :key="ri">
|
||||
<td v-for="(c, ci) in columns" :key="ci + 'c'">
|
||||
<span v-if="c.prop">{{ r[c.prop] }}</span>
|
||||
<span v-else-if="c.render">{{ c.render(r) }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@ -38,4 +42,18 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.list-item {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.list-enter-active, .list-leave-active {
|
||||
transition: all 1s;
|
||||
}
|
||||
.list-enter, .list-leave-to /* .list-leave-active below version 2.1.8 */ {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
</style>
|
||||
|
@ -1,8 +1,10 @@
|
||||
<template>
|
||||
<div class="Scroll-Table">
|
||||
<my-table :columns="columns" :rows="rows"></my-table>
|
||||
<div v-show="hasMore" v-if="!loading" v-observe-visibility="visibilityChanged">...</div>
|
||||
<div v-if="loading">loading...</div>
|
||||
<div v-if="loadingDelayed">loading...</div>
|
||||
<div style="padding-left: 30%; padding-bottom: 100px;">
|
||||
<span v-show="hasMore" v-if="!loadingDelayed" v-observe-visibility="visibilityChanged">...</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -56,15 +58,28 @@ export default {
|
||||
watch: {
|
||||
newRows(rows) {
|
||||
rows.forEach(row => {
|
||||
this.rows.push(row)
|
||||
this.rowsToPush.push(row);
|
||||
});
|
||||
this.currentOffset += rows.length;
|
||||
this.pushRows(); // for transition
|
||||
},
|
||||
loading(l) {
|
||||
if (!l) {
|
||||
// delay after loading for visibility observer
|
||||
setTimeout(() => {
|
||||
this.loadingDelayed = false;
|
||||
}, 200);
|
||||
} else {
|
||||
this.loadingDelayed = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
rows: [ ],
|
||||
currentOffset: this.offset
|
||||
rowsToPush: [ ],
|
||||
currentOffset: this.offset,
|
||||
loadingDelayed: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -73,6 +88,15 @@ export default {
|
||||
// infinite scrolling
|
||||
this.handler(this.currentOffset, this.limit);
|
||||
}
|
||||
},
|
||||
pushRows() {
|
||||
let row = this.rowsToPush.shift();
|
||||
if (row) {
|
||||
this.rows.push(row);
|
||||
setTimeout(() => {
|
||||
this.pushRows();
|
||||
}, 50);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,9 +49,7 @@ export default {
|
||||
.then(rows => {
|
||||
this.hasMore = (rows.length >= limit);
|
||||
this.newRows = rows;
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
}, 200); // for oberserver
|
||||
this.loading = false;
|
||||
})
|
||||
.catch(error => {
|
||||
this.loading = false;
|
||||
|
147
src/main.js
147
src/main.js
@ -7,6 +7,7 @@ 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);
|
||||
@ -25,6 +26,10 @@ const routes = [
|
||||
{
|
||||
path: '/userlist',
|
||||
component: Userlist
|
||||
},
|
||||
{
|
||||
path: '/logout',
|
||||
component: Logout
|
||||
}
|
||||
];
|
||||
|
||||
@ -36,35 +41,41 @@ const store = new Vuex.Store({
|
||||
state: {
|
||||
api: {},
|
||||
navigation: [],
|
||||
login: {},
|
||||
authToken: '',
|
||||
jwt: {},
|
||||
credentials: {}
|
||||
persist: {
|
||||
login: {},
|
||||
authToken: '',
|
||||
jwt: {},
|
||||
credentials: {}
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
setAPI(state, payload) {
|
||||
state.api = payload;
|
||||
},
|
||||
setNavigation(state, payload) {
|
||||
for (var i=0; i<payload.length; i++) {
|
||||
for (var i = 0; i < payload.length; i++) {
|
||||
state.navigation.push(payload[i]); // = payload;
|
||||
}
|
||||
},
|
||||
setCredentials(state, payload) {
|
||||
state.credentials = {
|
||||
state.persist.credentials = {
|
||||
username: payload.username,
|
||||
password: payload.password
|
||||
}
|
||||
};
|
||||
objectToPersist(state.persist, 'persistantStore');
|
||||
},
|
||||
setLogin(state, payload) {
|
||||
state.login = payload.User;
|
||||
state.authToken = payload.AuthToken;
|
||||
state.jwt = JwtDecode(payload.AuthToken);
|
||||
state.persist.login = payload.User;
|
||||
state.persist.authToken = payload.AuthToken;
|
||||
state.persist.jwt = JwtDecode(payload.AuthToken);
|
||||
objectToPersist(state.persist, 'persistantStore');
|
||||
},
|
||||
clearLogin() {
|
||||
state.login = {};
|
||||
state.authToken = '';
|
||||
state.jwt = {};
|
||||
clearLogin(state) {
|
||||
state.persist.login = {};
|
||||
state.persist.authToken = '';
|
||||
state.persist.jwt = {};
|
||||
state.persist.credentials = {};
|
||||
objectToPersist(state.persist, 'persistantStore');
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
@ -78,25 +89,25 @@ const store = new Vuex.Store({
|
||||
params: payload.params,
|
||||
data: payload.data,
|
||||
headers: {
|
||||
'X-Auth-Token': context.state.authToken
|
||||
'X-Auth-Token': context.state.persist.authToken
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
console.log(response);
|
||||
resolve(response.data);
|
||||
console.log(response);
|
||||
resolve(response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.dir(error);
|
||||
reject(error);
|
||||
console.dir(error);
|
||||
reject(error);
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
if (payload.endpoint != 'login') {
|
||||
// no jwt check for login call
|
||||
|
||||
|
||||
// empty username = not logged in
|
||||
if (!context.state.credentials.username) {
|
||||
if (!context.state.persist.credentials.username) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// show login page
|
||||
router.push('/login');
|
||||
@ -105,7 +116,7 @@ const store = new Vuex.Store({
|
||||
}
|
||||
|
||||
let now = Math.round(Date.now() / 1000);
|
||||
if ( context.state.jwt.exp < (now + 300) ) {
|
||||
if (context.state.persist.jwt.exp < (now + 300)) {
|
||||
// too old jwt, logout
|
||||
return new Promise((resolve, reject) => {
|
||||
context.commit('clearLogin');
|
||||
@ -114,11 +125,11 @@ const store = new Vuex.Store({
|
||||
});
|
||||
}
|
||||
|
||||
if ( (context.state.jwt.exp - 60) < now ) {
|
||||
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.credentials)
|
||||
return context.dispatch('login', context.state.persist.credentials)
|
||||
.then(() => {
|
||||
console.log("LOOOGIIIINNN");
|
||||
return doRequest();
|
||||
@ -144,43 +155,71 @@ const store = new Vuex.Store({
|
||||
resolve(data.User);
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.response && error.response.data && error.response.data.error) {
|
||||
reject(error.response.data.error);
|
||||
} else {
|
||||
reject([]);
|
||||
}
|
||||
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: ' + this.src);
|
||||
return;
|
||||
}
|
||||
store.commit("setNavigation", results.data.navigation);
|
||||
.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);
|
||||
// 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);
|
||||
});
|
||||
// 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);
|
||||
});
|
Loading…
Reference in New Issue
Block a user