mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
improve connection state detection
blocks all api calls until we are sure the user is connected. if session has expired, force reconnection.
This commit is contained in:
parent
bd148897f8
commit
88d7b736e2
5 changed files with 66 additions and 21 deletions
|
@ -9,7 +9,7 @@
|
|||
{{ $t('user_interface_link') }} <icon iname="user" class="sm"/>
|
||||
</b-button>
|
||||
</li>
|
||||
<li class="nav-item" v-bind:hidden="!connected">
|
||||
<li class="nav-item" v-show="connected">
|
||||
<b-button @click.prevent="logout" to="/logout" variant="outline-dark" block size="sm" >
|
||||
{{ $t('logout') }} <icon iname="sign-out" class="sm"/>
|
||||
</b-button>
|
||||
|
@ -19,7 +19,7 @@
|
|||
</header>
|
||||
|
||||
<main>
|
||||
<router-view/>
|
||||
<router-view v-if="isReady"/>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
|
@ -34,7 +34,11 @@
|
|||
<b-nav-item href="https://donate.yunohost.org/" target="_blank" link-classes='text-secondary'>
|
||||
<icon iname="heart" class="sm"/> Donate
|
||||
</b-nav-item>
|
||||
<b-nav-text class="ml-auto" id="yunohost-version">version</b-nav-text>
|
||||
<i18n v-if="yunohostInfos" path="footer_version" tag="b-nav-text" class="ml-auto" id="yunohost-version">
|
||||
<template v-slot:ynh><b-link href="https://yunohost.org">YunoHost</b-link></template>
|
||||
<template v-slot:version>{{ yunohostInfos.version }}</template>
|
||||
<template v-slot:repo>{{ yunohostInfos.repo }}</template>
|
||||
</i18n>
|
||||
</b-nav>
|
||||
</nav>
|
||||
</footer>
|
||||
|
@ -42,25 +46,54 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
import api from '@/helpers/api'
|
||||
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
computed: {
|
||||
connected: function () {
|
||||
return this.$store.state.connected
|
||||
data: () => {
|
||||
return {
|
||||
// isReady blocks the rendering of the rooter-view until we have a true info
|
||||
// about the connected state of the user.
|
||||
isReady: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['connected', 'yunohostInfos']),
|
||||
},
|
||||
methods: {
|
||||
async logout() {
|
||||
const disconnected = await api.logout()
|
||||
if (disconnected) {
|
||||
this.$store.commit('CONNECTED', false);
|
||||
this.$router.push('/login')
|
||||
}
|
||||
}
|
||||
await api.logout()
|
||||
this.$store.commit('CONNECTED', false);
|
||||
this.$router.push('/login')
|
||||
},
|
||||
},
|
||||
// This hook is only triggered at page reload so the value of state.connected
|
||||
// always come from the localStorage
|
||||
async created() {
|
||||
if (!this.$store.state.connected) {
|
||||
// user is not connected: allow the login view to be rendered.
|
||||
this.isReady = true
|
||||
return
|
||||
}
|
||||
// localStorage 'connected' value may be true, but session may have expired.
|
||||
// Try to get the yunohost version.
|
||||
try {
|
||||
const data = await api.getVersion()
|
||||
this.$store.commit('YUNOHOST_INFOS', data.yunohost)
|
||||
} catch (err) {
|
||||
// Session expired, reset the 'connected' state and redirect with a query
|
||||
// FIXME is there a case where the error may not be a 401 therefor requires
|
||||
// better handling ?
|
||||
this.$store.commit('CONNECTED', false);
|
||||
this.$router.push({name: 'login', query: {redirect: this.$route.path}})
|
||||
} finally {
|
||||
// in any case allow the router-view to be rendered
|
||||
this.isReady = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -99,12 +132,12 @@ footer {
|
|||
font-size: 0.875rem;
|
||||
margin-top: 2rem;
|
||||
|
||||
li {
|
||||
.nav-item {
|
||||
&:not(:first-child) a::before {
|
||||
content: "•";
|
||||
width: 1rem;
|
||||
display: inline-block;
|
||||
margin-left: -1rem;
|
||||
margin-left: -1.15rem;
|
||||
}
|
||||
&:first-child {
|
||||
margin-left: -1rem;
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
"everything_good": "Everything good!",
|
||||
"experimental_warning": "Warning: this feature is experimental and not consider stable, you shouldn't be using it except if you know what you are doing.",
|
||||
"firewall": "Firewall",
|
||||
"footer_version": "Powered by <a href='https://yunohost.org'>YunoHost</a> %s (%s).",
|
||||
"footer_version": "Powered by {ynh} {version} ({repo}).",
|
||||
"form_input_example": "Example: %s",
|
||||
"from_to": "from %s to %s",
|
||||
"good_practices_about_admin_password": "You are now about to define a new admin password. The password should be at least 8 characters - though it is good practice to use longer password (i.e. a passphrase) and/or to use various kind of characters (uppercase, lowercase, digits and special characters).",
|
||||
|
|
|
@ -18,7 +18,7 @@ router.beforeEach((to, from, next) => {
|
|||
if (store.state.connected || to.meta.noAuth) {
|
||||
next()
|
||||
} else {
|
||||
next({path: '/login', query: {redirect: to.path}})
|
||||
next({name: 'login', query: {redirect: to.path}})
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -6,14 +6,24 @@ Vue.use(Vuex)
|
|||
|
||||
export default new Vuex.Store({
|
||||
state: {
|
||||
connected: localStorage.getItem('connected') === 'true'
|
||||
connected: localStorage.getItem('connected') === 'true',
|
||||
yunohostInfos: null
|
||||
},
|
||||
// Mutations must be synchronous. They are used to change the store state.
|
||||
mutations: {
|
||||
['CONNECTED'] (state, connected) {
|
||||
localStorage.setItem('connected', connected)
|
||||
state.connected = connected
|
||||
if (!connected) {
|
||||
state.yunohostInfos = null
|
||||
}
|
||||
},
|
||||
['YUNOHOST_INFOS'] (state, data) {
|
||||
console.log('version changed', data);
|
||||
state.yunohostInfos = data
|
||||
}
|
||||
},
|
||||
// Actions may be asynchronous. They are used to commit mutations.
|
||||
actions: {
|
||||
},
|
||||
modules: {
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
v-model="password"
|
||||
type="password"
|
||||
:placeholder="$t('administration_password')"
|
||||
:state="state"
|
||||
:state="isValid"
|
||||
></b-form-input>
|
||||
<template v-slot:append>
|
||||
<b-button type="submit" variant="success">{{ $t('login') }}</b-button>
|
||||
</template>
|
||||
</b-input-group>
|
||||
<b-form-invalid-feedback :state="state">
|
||||
<b-form-invalid-feedback :state="isValid">
|
||||
{{ $t('wrong_password') }}
|
||||
</b-form-invalid-feedback>
|
||||
</b-form>
|
||||
|
@ -33,7 +33,7 @@ export default {
|
|||
data: () => {
|
||||
return {
|
||||
password: '',
|
||||
state: null,
|
||||
isValid: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -42,9 +42,11 @@ export default {
|
|||
if (connected) {
|
||||
this.$store.commit('CONNECTED', true);
|
||||
this.$router.push(this.$route.query.redirect || '/')
|
||||
const infos = await api.getVersion();
|
||||
this.$store.commit('YUNOHOST_INFOS', infos.yunohost)
|
||||
} else {
|
||||
this.$store.commit('CONNECTED', false);
|
||||
this.state = false
|
||||
this.isValid = false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue