mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
* feat(frontend): migration fixes * feat(admin): post migration fixes * feat(admin): revert docker change * feat(admin): update tests
124 lines
3.2 KiB
Vue
124 lines
3.2 KiB
Vue
<template>
|
|
<div class="session-logout-timeout">
|
|
<BModal
|
|
id="modalSessionTimeOut"
|
|
class="bg-variant-danger"
|
|
hide-header-close
|
|
hide-header
|
|
hide-footer
|
|
no-close-on-backdrop
|
|
:model-value="sessionModalModel"
|
|
@update:modelValue="sessionModalModel = $event"
|
|
>
|
|
<BCard header-tag="header" footer-tag="footer">
|
|
<BCardText>
|
|
<div class="p-3 h2">{{ $t('session.warningText') }}</div>
|
|
<div class="p-3">
|
|
{{ $t('session.lightText') }}
|
|
</div>
|
|
<div class="p-3 h2 text-warning">
|
|
{{ $t('session.logoutIn') }}
|
|
<b>{{ formatTime(remainingTime) }}</b>
|
|
{{ $t('time.seconds') }}
|
|
</div>
|
|
</BCardText>
|
|
<BRow>
|
|
<BCol class="text-center">
|
|
<BButton size="lg" variant="success" @click="handleOk">
|
|
{{ $t('session.extend') }}
|
|
</BButton>
|
|
</BCol>
|
|
</BRow>
|
|
</BCard>
|
|
<template #modal-footer>
|
|
<BButton size="sm" variant="danger" @click="emit('logout')">
|
|
{{ $t('navigation.logout') }}
|
|
</BButton>
|
|
<BButton size="lg" variant="success" @click="handleOk">
|
|
{{ $t('session.extend') }}
|
|
</BButton>
|
|
</template>
|
|
</BModal>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, onBeforeUnmount, watch, onMounted, onUnmounted } from 'vue'
|
|
import { useStore } from 'vuex'
|
|
import { useLazyQuery } from '@vue/apollo-composable'
|
|
import { verifyLogin } from '@/graphql/queries'
|
|
import { useModal } from 'bootstrap-vue-next'
|
|
|
|
const store = useStore()
|
|
const emit = defineEmits(['logout'])
|
|
|
|
const sessionModalModel = ref(false)
|
|
const { hide: hideModal } = useModal('modalSessionTimeOut')
|
|
|
|
const { load: verifyLoginQuery, loading, error } = useLazyQuery(verifyLogin)
|
|
|
|
const remainingTime = ref(0)
|
|
let intervalId = null
|
|
|
|
const tokenExpirationTime = computed(() => new Date(store.state.tokenTime * 1000))
|
|
|
|
const isTokenValid = computed(() => {
|
|
return remainingTime.value > 0
|
|
})
|
|
|
|
const calculateRemainingTime = () => {
|
|
const now = new Date()
|
|
const diff = tokenExpirationTime.value - now
|
|
remainingTime.value = Math.max(0, Math.floor(diff / 1000))
|
|
// Show modal if remaining time is 75 seconds or less
|
|
if (remainingTime.value <= 75) {
|
|
sessionModalModel.value = true
|
|
}
|
|
// Clear interval if time expired
|
|
if (remainingTime.value <= 0) {
|
|
clearInterval(intervalId)
|
|
}
|
|
}
|
|
|
|
const formatTime = (seconds) => {
|
|
if (seconds <= 0) return '00'
|
|
|
|
const remainingSeconds = seconds % 60
|
|
return `${remainingSeconds.toString().padStart(2, '0')}`
|
|
}
|
|
|
|
onMounted(() => {
|
|
calculateRemainingTime()
|
|
|
|
if (isTokenValid.value) {
|
|
intervalId = setInterval(calculateRemainingTime, 1000)
|
|
}
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
if (intervalId) {
|
|
clearInterval(intervalId)
|
|
}
|
|
})
|
|
|
|
watch(remainingTime, (newTime) => {
|
|
if (newTime <= 0) {
|
|
emit('logout')
|
|
}
|
|
})
|
|
|
|
const handleOk = async (bvModalEvent) => {
|
|
bvModalEvent.preventDefault()
|
|
try {
|
|
await verifyLoginQuery()
|
|
if (error.value) {
|
|
emit('logout')
|
|
throw new Error('Login verification failed')
|
|
}
|
|
hideModal('modalSessionTimeOut')
|
|
} catch {
|
|
emit('logout')
|
|
}
|
|
}
|
|
</script>
|