Consistent and stronger session revalidation checks in Auth profile and Admin App. Fix missing handling of link generation network errors.
This commit is contained in:
@@ -38,6 +38,7 @@ import QRCodeDisplay from '@/components/QRCodeDisplay.vue'
|
||||
import { apiJson } from '@/utils/api'
|
||||
import { formatDate } from '@/utils/helpers'
|
||||
import { getDirection } from '@/utils/keynav'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
const props = defineProps({
|
||||
endpoint: { type: String, required: true },
|
||||
@@ -46,6 +47,7 @@ const props = defineProps({
|
||||
|
||||
const emit = defineEmits(['close', 'copied'])
|
||||
|
||||
const authStore = useAuthStore()
|
||||
const dialog = ref(null)
|
||||
const linkUrl = ref(null)
|
||||
const expiresAt = ref(null)
|
||||
@@ -73,7 +75,8 @@ async function generateLink() {
|
||||
} else {
|
||||
emit('close')
|
||||
}
|
||||
} catch {
|
||||
} catch (e) {
|
||||
authStore.showMessage(e.message || 'Failed to generate link', 'error')
|
||||
emit('close')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import { onMounted, onUnmounted } from 'vue'
|
||||
import { apiJson } from './api'
|
||||
|
||||
const POLL_INTERVAL = 60 * 1000
|
||||
const IDLE_TIMEOUT = 5 * 60 * 1000
|
||||
|
||||
export function useSessionValidation(userUuid, onSessionLost) {
|
||||
let pollTimer = null
|
||||
let idleTimer = null
|
||||
let active = false
|
||||
|
||||
function resetIdleTimer() {
|
||||
if (idleTimer) clearTimeout(idleTimer)
|
||||
if (!active) startPolling()
|
||||
idleTimer = setTimeout(stopPolling, IDLE_TIMEOUT)
|
||||
}
|
||||
|
||||
async function validate() {
|
||||
try {
|
||||
const data = await apiJson('/auth/api/validate', { method: 'POST' })
|
||||
const newUuid = data.ctx?.user?.uuid
|
||||
if (newUuid !== userUuid.value) {
|
||||
window.location.reload()
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.name !== 'NetworkError') {
|
||||
stopPolling()
|
||||
onSessionLost(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function startPolling() {
|
||||
if (active) return
|
||||
active = true
|
||||
pollTimer = setInterval(validate, POLL_INTERVAL)
|
||||
}
|
||||
|
||||
function stopPolling() {
|
||||
active = false
|
||||
if (pollTimer) {
|
||||
clearInterval(pollTimer)
|
||||
pollTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('pointermove', resetIdleTimer)
|
||||
window.addEventListener('pointerdown', resetIdleTimer)
|
||||
resetIdleTimer()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('pointermove', resetIdleTimer)
|
||||
window.removeEventListener('pointerdown', resetIdleTimer)
|
||||
if (idleTimer) clearTimeout(idleTimer)
|
||||
stopPolling()
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user