Add an Auto Lock page to enforce logout et prevent CSRF mismatch error

(completes #73 fix)
This commit is contained in:
Bubka 2022-07-13 14:56:25 +02:00
parent aa3c1e9008
commit a2c4348364
5 changed files with 39 additions and 12 deletions

8
resources/js/api.js vendored
View File

@ -48,12 +48,8 @@ Vue.axios.interceptors.response.use(response => response, error => {
// api calls are stateless so when user inactivity is detected // api calls are stateless so when user inactivity is detected
// by the backend middleware it cannot logout the user directly // by the backend middleware it cannot logout the user directly
// so it returns a 418 response. // so it returns a 418 response.
// We catch the 418 response and push the user to the login view // We catch the 418 response and push the user to the autolock view
// with the instruction to request a session logout if ( error.response.status === 418 ) routeName = 'autolock'
if ( error.response.status === 418 ) {
router.push({ name: 'login', params: { forceLogout: true } })
throw new Vue.axios.Cancel();
}
if ( error.response.status === 404 ) routeName = '404' if ( error.response.status === 404 ) routeName = '404'

View File

@ -43,7 +43,7 @@
clearTimeout(this.logoutTimer) clearTimeout(this.logoutTimer)
this.appLogout() this.$router.push({ name: 'autolock' })
}, },
resetTimer: function() { resetTimer: function() {

View File

@ -15,6 +15,7 @@ import CreateGroup from './views/groups/Create'
import EditGroup from './views/groups/Edit' import EditGroup from './views/groups/Edit'
import Login from './views/auth/Login' import Login from './views/auth/Login'
import Register from './views/auth/Register' import Register from './views/auth/Register'
import Autolock from './views/auth/Autolock'
import PasswordRequest from './views/auth/password/Request' import PasswordRequest from './views/auth/password/Request'
import PasswordReset from './views/auth/password/Reset' import PasswordReset from './views/auth/password/Reset'
import WebauthnLost from './views/auth/webauthn/Lost' import WebauthnLost from './views/auth/webauthn/Lost'
@ -52,13 +53,15 @@ const router = new Router({
{ path: '/login', name: 'login', component: Login, meta: { disabledWithAuthProxy: true } }, { path: '/login', name: 'login', component: Login, meta: { disabledWithAuthProxy: true } },
{ path: '/register', name: 'register', component: Register, meta: { disabledWithAuthProxy: true } }, { path: '/register', name: 'register', component: Register, meta: { disabledWithAuthProxy: true } },
{ path: '/autolock', name: 'autolock',component: Autolock, meta: { disabledWithAuthProxy: true } },
{ path: '/password/request', name: 'password.request', component: PasswordRequest, meta: { disabledWithAuthProxy: true } }, { path: '/password/request', name: 'password.request', component: PasswordRequest, meta: { disabledWithAuthProxy: true } },
{ path: '/password/reset/:token', name: 'password.reset', component: PasswordReset, meta: { disabledWithAuthProxy: true } }, { path: '/password/reset/:token', name: 'password.reset', component: PasswordReset, meta: { disabledWithAuthProxy: true } },
{ path: '/webauthn/lost', name: 'webauthn.lost', component: WebauthnLost, meta: { disabledWithAuthProxy: true } }, { path: '/webauthn/lost', name: 'webauthn.lost', component: WebauthnLost, meta: { disabledWithAuthProxy: true } },
{ path: '/webauthn/recover', name: 'webauthn.recover', component: WebauthnRecover, meta: { disabledWithAuthProxy: true } }, { path: '/webauthn/recover', name: 'webauthn.recover', component: WebauthnRecover, meta: { disabledWithAuthProxy: true } },
{ path: '/flooded', name: 'flooded',component: Errors,props: true },
{ path: '/error', name: 'genericError',component: Errors,props: true }, { path: '/flooded', name: 'flooded',component: Errors, props: true },
{ path: '/404', name: '404',component: Errors,props: true }, { path: '/error', name: 'genericError',component: Errors, props: true },
{ path: '/404', name: '404',component: Errors, props: true },
{ path: '*', redirect: { name: '404' } } { path: '*', redirect: { name: '404' } }
], ],
}); });

View File

@ -0,0 +1,25 @@
<template>
<form-wrapper :title="$t('auth.autolock_triggered')" :punchline="$t('auth.autolock_triggered_punchline')">
<p>{{ $t('auth.change_autolock_in_settings') }}</p>
<div class="nav-links">
<p><router-link :to="{ name: 'login', params: {forceRefresh : true} }" class="button is-link">{{ $t('auth.sign_in') }}</router-link></p>
</div>
</form-wrapper>
</template>
<script>
export default {
data(){
return {
}
},
mounted() {
this.axios.get('/user/logout', {returnError: true}).catch(error => {
// there is nothing to do, we simply catch the error to avoid redondant navigation
});
this.$storage.clear()
},
}
</script>

View File

@ -131,9 +131,12 @@
}, },
beforeRouteEnter (to, from, next) { beforeRouteEnter (to, from, next) {
next(async vm => { if (to.params.forceRefresh && from.name !== null) {
if( to.params.forceLogout ) await vm.axios.get('/user/logout') window.location.href = to.path;
return;
}
next(async vm => {
const { data } = await vm.axios.get('api/v1/user/name') const { data } = await vm.axios.get('api/v1/user/name')
if( data.name ) { if( data.name ) {