Change the Kicker activation method to ensure minified code works as well

This commit is contained in:
Bubka 2023-11-30 13:18:35 +01:00
parent 333b70e688
commit 3459a364a0
7 changed files with 73 additions and 60 deletions

View File

@ -1,17 +1,18 @@
<script setup>
import { RouterView } from 'vue-router'
const route = useRoute()
const kickUser = ref(null)
const kickUserAfter = ref(null)
const isProtectedRoute = ref(null)
const isProtectedRoute = ref(route.meta.watchedByKicker)
watch(
() => route.name,
() => {
isProtectedRoute.value = protectedRoute(route)
isProtectedRoute.value = route.meta.watchedByKicker
}
)
const kickInactiveUser = computed(() => kickUserAfter.value > 0 && isProtectedRoute.value)
// const kickInactiveUser = computed(() => kickUser && kickUserAfter.value > 0 && isProtectedRoute.value)
onBeforeMount(async () => {
const { useUserStore } = await import('./stores/user.js')
@ -19,7 +20,7 @@
const user = useUserStore()
kickUserAfter.value = parseInt(user.preferences.kickUserAfter)
isProtectedRoute.value = protectedRoute(route)
kickUser.value = user.isAuthenticated
watch(
() => user.preferences.kickUserAfter,
@ -27,23 +28,17 @@
kickUserAfter.value = parseInt(user.preferences.kickUserAfter)
}
)
watch(
() => user.isAuthenticated,
() => {
kickUser.value = user.isAuthenticated
}
)
watch(language, () => {
user.applyLanguage()
})
})
function protectedRoute(route) {
let bool = false
route.meta.middlewares?.forEach(func => {
if (func instanceof Function && func.name == 'authGuard') {
bool = true
return
}
})
return bool
}
</script>
<template>
@ -59,5 +54,5 @@
<main class="main-section">
<RouterView />
</main>
<kicker v-if="kickInactiveUser" :kickAfter="kickUserAfter"></kicker>
<kicker v-if="kickUser && kickUserAfter > 0 && isProtectedRoute" :kickAfter="kickUserAfter"></kicker>
</template>

View File

@ -2,7 +2,7 @@
import { useUserStore } from '@/stores/user'
const user = useUserStore()
const events = ref(['click', 'mousedown', 'scroll', 'keypress', 'load'])
const events = ref(['mousedown', 'scroll', 'keypress'])
const logoutTimer = ref(null)
// const elapsed = ref(0)
// const counter = ref(null)
@ -14,45 +14,54 @@
},
})
watch(
() => props.kickAfter,
() => {
restartTimer()
}
)
onMounted(() => {
events.value.forEach(function (event) {
window.addEventListener(event, resetTimer)
window.addEventListener(event, restartTimer)
}, this)
setTimer()
startTimer()
})
onUnmounted(() => {
events.value.forEach(function (event) {
window.removeEventListener(event, resetTimer)
window.removeEventListener(event, restartTimer)
}, this)
clearTimeout(logoutTimer.value)
// clearInterval(counter.value)
stopTimer()
})
function setTimer() {
// elapsed.value = 0
// clearInterval(counter.value)
function startTimer() {
logoutTimer.value = setTimeout(logoutUser, props.kickAfter * 60 * 1000)
// counter.value = setInterval(() => {
// elapsed.value += 1
// console.log(elapsed.value + '/' + props.kickAfter * 60)
// }, 1000);
// }, 1000)
}
// Triggers the user logout
function logoutUser() {
clearTimeout(logoutTimer.value)
console.log('inativity detected, user kicked out')
user.logout({ kicked: true})
}
function resetTimer() {
// Restarts the timer
function restartTimer() {
stopTimer()
startTimer()
}
// Stops the timer
function stopTimer() {
clearTimeout(logoutTimer.value)
setTimer()
// elapsed.value = 0
// clearInterval(counter.value)
}
</script>

View File

@ -14,24 +14,24 @@ import setReturnTo from './middlewares/setReturnTo'
const router = createRouter({
history: createWebHistory('/'),
routes: [
{ path: '/start', name: 'start', component: () => import('../views/Start.vue'), meta: { middlewares: [authGuard, setReturnTo] } },
{ path: '/capture', name: 'capture', component: () => import('../views/twofaccounts/Capture.vue'), meta: { middlewares: [authGuard, setReturnTo] } },
{ path: '/start', name: 'start', component: () => import('../views/Start.vue'), meta: { middlewares: [authGuard, setReturnTo], watchedByKicker: true } },
{ path: '/capture', name: 'capture', component: () => import('../views/twofaccounts/Capture.vue'), meta: { middlewares: [authGuard, setReturnTo], watchedByKicker: true } },
{ path: '/accounts', name: 'accounts', component: () => import('../views/twofaccounts/Accounts.vue'), meta: { middlewares: [authGuard, starter, setReturnTo] }, alias: '/' },
{ path: '/account/create', name: 'createAccount', component: () => import('../views/twofaccounts/CreateUpdate.vue'), meta: { middlewares: [authGuard, setReturnTo] } },
{ path: '/account/import', name: 'importAccounts', component: () => import('../views/twofaccounts/Import.vue'), meta: { middlewares: [authGuard, setReturnTo] } },
{ path: '/account/:twofaccountId/edit', name: 'editAccount', component: () => import('../views/twofaccounts/CreateUpdate.vue'), meta: { middlewares: [authGuard, setReturnTo] }, props: true },
{ path: '/account/:twofaccountId/qrcode', name: 'showQRcode', component: () => import('../views/twofaccounts/QRcode.vue'), meta: { middlewares: [authGuard, setReturnTo] } },
{ path: '/accounts', name: 'accounts', component: () => import('../views/twofaccounts/Accounts.vue'), meta: { middlewares: [authGuard, starter, setReturnTo], watchedByKicker: true }, alias: '/' },
{ path: '/account/create', name: 'createAccount', component: () => import('../views/twofaccounts/CreateUpdate.vue'), meta: { middlewares: [authGuard, setReturnTo], watchedByKicker: true } },
{ path: '/account/import', name: 'importAccounts', component: () => import('../views/twofaccounts/Import.vue'), meta: { middlewares: [authGuard, setReturnTo], watchedByKicker: true } },
{ path: '/account/:twofaccountId/edit', name: 'editAccount', component: () => import('../views/twofaccounts/CreateUpdate.vue'), meta: { middlewares: [authGuard, setReturnTo], watchedByKicker: true }, props: true },
{ path: '/account/:twofaccountId/qrcode', name: 'showQRcode', component: () => import('../views/twofaccounts/QRcode.vue'), meta: { middlewares: [authGuard, setReturnTo], watchedByKicker: true } },
{ path: '/groups', name: 'groups', component: () => import('../views/groups/Groups.vue'), meta: { middlewares: [authGuard, setReturnTo] }, props: true },
{ path: '/group/create', name: 'createGroup', component: () => import('../views/groups/CreateUpdate.vue'), meta: { middlewares: [authGuard, setReturnTo] } },
{ path: '/group/:groupId/edit', name: 'editGroup', component: () => import('../views/groups/CreateUpdate.vue'), meta: { middlewares: [authGuard, setReturnTo] }, props: true },
{ path: '/groups', name: 'groups', component: () => import('../views/groups/Groups.vue'), meta: { middlewares: [authGuard, setReturnTo], watchedByKicker: true }, props: true },
{ path: '/group/create', name: 'createGroup', component: () => import('../views/groups/CreateUpdate.vue'), meta: { middlewares: [authGuard, setReturnTo], watchedByKicker: true } },
{ path: '/group/:groupId/edit', name: 'editGroup', component: () => import('../views/groups/CreateUpdate.vue'), meta: { middlewares: [authGuard, setReturnTo], watchedByKicker: true }, props: true },
{ path: '/settings/options', name: 'settings.options', component: () => import('../views/settings/Options.vue'), meta: { middlewares: [authGuard], showAbout: true } },
{ path: '/settings/account', name: 'settings.account', component: () => import('../views/settings/Account.vue'), meta: { middlewares: [authGuard], showAbout: true } },
{ path: '/settings/oauth', name: 'settings.oauth.tokens', component: () => import('../views/settings/OAuth.vue'), meta: { middlewares: [authGuard], showAbout: true, props: true } },
{ path: '/settings/webauthn/:credentialId/edit', name: 'settings.webauthn.editCredential', component: () => import('../views/settings/Credentials/Edit.vue'), meta: { middlewares: [authGuard], showAbout: true }, props: true },
{ path: '/settings/webauthn', name: 'settings.webauthn.devices', component: () => import('../views/settings/WebAuthn.vue'), meta: { middlewares: [authGuard], showAbout: true } },
{ path: '/settings/options', name: 'settings.options', component: () => import('../views/settings/Options.vue'), meta: { middlewares: [authGuard], watchedByKicker: true, showAbout: true } },
{ path: '/settings/account', name: 'settings.account', component: () => import('../views/settings/Account.vue'), meta: { middlewares: [authGuard], watchedByKicker: true, showAbout: true } },
{ path: '/settings/oauth', name: 'settings.oauth.tokens', component: () => import('../views/settings/OAuth.vue'), meta: { middlewares: [authGuard], watchedByKicker: true, showAbout: true, props: true } },
{ path: '/settings/webauthn/:credentialId/edit', name: 'settings.webauthn.editCredential', component: () => import('../views/settings/Credentials/Edit.vue'), meta: { middlewares: [authGuard], watchedByKicker: true, showAbout: true }, props: true },
{ path: '/settings/webauthn', name: 'settings.webauthn.devices', component: () => import('../views/settings/WebAuthn.vue'), meta: { middlewares: [authGuard], watchedByKicker: true, showAbout: true } },
{ path: '/login', name: 'login', component: () => import('../views/auth/Login.vue'), meta: { middlewares: [setReturnTo], disabledWithAuthProxy: true, showAbout: true } },
{ path: '/register', name: 'register', component: () => import('../views/auth/Register.vue'), meta: { middlewares: [noRegistration, setReturnTo], disabledWithAuthProxy: true, showAbout: true } },
@ -40,10 +40,10 @@ const router = createRouter({
{ path: '/webauthn/lost', name: 'webauthn.lost', component: () => import('../views/auth/RequestReset.vue'), meta: { middlewares: [setReturnTo], disabledWithAuthProxy: true, showAbout: true } },
{ path: '/webauthn/recover', name: 'webauthn.recover', component: () => import('../views/auth/webauthn/Recover.vue'), meta: { middlewares: [setReturnTo], disabledWithAuthProxy: true, showAbout: true } },
{ path: '/about', name: 'about', component: () => import('../views/About.vue'), meta: { showAbout: true } },
{ path: '/error', name: 'genericError', component: () => import('../views/Error.vue'), meta: { middlewares: [noEmptyError] } },
{ path: '/404', name: '404', component: () => import('../views/Error.vue'), props: true },
{ path: '/:pathMatch(.*)*', name: 'notFound', component: () => import('../views/Error.vue'), props: true },
{ path: '/about', name: 'about', component: () => import('../views/About.vue'), meta: { showAbout: true, watchedByKicker: true } },
{ path: '/error', name: 'genericError', component: () => import('../views/Error.vue'), meta: { middlewares: [noEmptyError], watchedByKicker: true } },
{ path: '/404', name: '404', component: () => import('../views/Error.vue'), meta: { watchedByKicker: true }, props: true },
{ path: '/:pathMatch(.*)*', name: 'notFound', component: () => import('../views/Error.vue'), meta: { watchedByKicker: true }, props: true },
]
})

View File

@ -7,8 +7,8 @@ export default {
/**
*
*/
logout() {
return webClient.get('/user/logout')
logout(config = {}) {
return webClient.get('/user/logout', { ...config })
},
/**

View File

@ -58,7 +58,7 @@ export const httpClientFactory = (endpoint = 'api') => {
if (error.response && [401].includes(error.response.status)) {
const user = useUserStore()
user.reset()
user.tossOut()
}
// Always return the form validation errors

View File

@ -58,6 +58,7 @@ export const useUserStore = defineStore({
*/
logout(options = {}) {
const { kicked } = options
const notify = useNotifyStore()
// async appLogout(evt) {
if (this.$2fauth.config.proxyAuth) {
@ -67,21 +68,29 @@ export const useUserStore = defineStore({
else return false
}
else {
return authService.logout().then(() => {
this.reset()
authService.logout({ returnError: true }).then(() => {
if (kicked) {
const notify = useNotifyStore()
notify.clear()
notify.warn({ text: trans('auth.autolock_triggered_punchline'), duration:-1 })
}
this.tossOut()
})
.catch(error => {
// The logout request will receive a 401 response when the
// backend has already detect inactivity on its side. In this case we
// don't want any error to be displayed.
if (error.response.status !== 401) {
notify.error(error)
}
else this.tossOut()
})
}
},
/**
* Resets all user data
* Resets all user data and push out
*/
reset() {
tossOut() {
this.$reset()
this.initDataStores()
this.applyUserPrefs()

View File

@ -27,7 +27,7 @@
'register' => 'Register',
'welcome_to_2fauth' => 'Welcome to 2FAuth',
'autolock_triggered' => 'Auto lock triggered',
'autolock_triggered_punchline' => 'Auto-lock triggered and logged you out',
'autolock_triggered_punchline' => 'Auto-lock triggered, you\'ve been logged out',
'already_authenticated' => 'Already authenticated, please log out first',
'authentication' => 'Authentication',
'maybe_later' => 'Maybe later',