Set up Kicker to log out user when inactivity is detected

This commit is contained in:
Bubka 2023-10-07 17:15:41 +02:00
parent abce4a0a7a
commit bde05233c5
4 changed files with 110 additions and 4 deletions

View File

@ -1,14 +1,49 @@
<script setup>
import { RouterView } from 'vue-router'
const route = useRoute()
const kickUserAfter = ref(null)
const isProtectedRoute = ref(null)
onMounted(async () => {
const { useUserStore } = await import('./stores/user.js');
watch(
() => route.name,
() => {
isProtectedRoute.value = protectedRoute(route)
}
)
const kickInactiveUser = computed(() => kickUserAfter.value > 0 && isProtectedRoute.value)
onBeforeMount(async () => {
const { useUserStore } = await import('./stores/user.js')
const { language } = useNavigatorLanguage()
const user = useUserStore()
kickUserAfter.value = parseInt(user.preferences.kickUserAfter)
isProtectedRoute.value = protectedRoute(route)
watch(
() => user.preferences.kickUserAfter,
() => {
kickUserAfter.value = parseInt(user.preferences.kickUserAfter)
}
)
watch(language, () => {
useUserStore().applyLanguage()
user.applyLanguage()
})
})
function protectedRoute(route) {
let bool = false
route.meta.middlewares?.forEach(func => {
if (func instanceof Function && func.name == 'auth') {
bool = true
return
}
})
return bool
}
</script>
<template>
@ -16,4 +51,5 @@
<main class="main-section">
<RouterView />
</main>
<kicker v-if="kickInactiveUser" :kickAfter="kickUserAfter"></kicker>
</template>

View File

@ -56,7 +56,7 @@ import FormSelect from '@/components/formElements/FormSelect.vue'
import FormToggle from '@/components/formElements/FormToggle.vue'
import FormCheckbox from '@/components/formElements/FormCheckbox.vue'
import FormButtons from '@/components/formElements/FormButtons.vue'
// import Kicker from './Kicker'
import Kicker from '@/components/Kicker.vue'
// import SettingTabs from './SettingTabs'
app
@ -73,6 +73,7 @@ app
.component('FormToggle', FormToggle)
.component('FormCheckbox', FormCheckbox)
.component('FormButtons', FormButtons)
.component('Kicker', Kicker)
// Global error handling
import { useNotifyStore } from '@/stores/notify'

View File

@ -0,0 +1,60 @@
<script setup>
import { useUserStore } from '@/stores/user'
const user = useUserStore()
const events = ref(['click', 'mousedown', 'scroll', 'keypress', 'load'])
const logoutTimer = ref(null)
// const elapsed = ref(0)
// const counter = ref(null)
const props = defineProps({
kickAfter: {
type: Number,
required: true
},
})
onMounted(() => {
events.value.forEach(function (event) {
window.addEventListener(event, resetTimer)
}, this)
setTimer()
})
onUnmounted(() => {
events.value.forEach(function (event) {
window.removeEventListener(event, resetTimer)
}, this)
clearTimeout(logoutTimer.value)
// clearInterval(counter.value)
})
function setTimer() {
// elapsed.value = 0
// clearInterval(counter.value)
logoutTimer.value = setTimeout(logoutUser, props.kickAfter * 60 * 1000)
// counter.value = setInterval(() => {
// elapsed.value += 1
// console.log(elapsed.value + '/' + props.kickAfter * 60)
// }, 1000);
}
function logoutUser() {
clearTimeout(logoutTimer.value)
console.log('inativity detected, user kicked out')
user.logout()
}
function resetTimer() {
clearTimeout(logoutTimer.value)
setTimer()
}
</script>
<template>
</template>

View File

@ -66,6 +66,15 @@ export const httpClientFactory = (endpoint = 'api') => {
return Promise.reject(error)
}
// api calls are stateless so when user inactivity is detected
// by the backend middleware, it cannot logout the user directly
// so it returns a 418 response.
// We catch the 418 response and push the user to the autolock view
if ( error.response.status === 418 ) {
const user = useUserStore()
user.logout()
}
useNotifyStore().error(error)
return new Promise(() => {})
}