Files
frontend/app/pages/auth/cie/callback.vue
T

127 lines
3.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from 'vue'
definePageMeta({
middleware: 'guest'
})
useHead({ title: 'Accesso CIE - Visione' })
const route = useRoute()
const router = useRouter()
const { fetchCieSession, handleLoginSuccess } = useAuth()
const state = computed(() => {
const value = route.query.state
return typeof value === 'string' ? value : ''
})
const isLoading = ref(true)
const errorMessage = ref('')
const statusMessage = ref('Verifica dell’autenticazione CIE in corso...')
let pollTimer: ReturnType<typeof setTimeout> | null = null
let attempts = 0
const maxAttempts = 30
const stopPolling = () => {
if (pollTimer) {
clearTimeout(pollTimer)
pollTimer = null
}
}
const scheduleNextPoll = () => {
pollTimer = setTimeout(checkSession, 2000)
}
const redirectToLoginError = async (code: string, fallbackMessage: string) => {
stopPolling()
isLoading.value = false
try {
await router.replace({
path: '/auth/login',
query: { cie_error: code }
})
} catch {
errorMessage.value = fallbackMessage
}
}
const checkSession = async () => {
if (!state.value) {
await redirectToLoginError('invalid_session', 'Sessione CIE non valida: parametro state mancante.')
return
}
attempts += 1
try {
const res = await fetchCieSession(state.value)
if (res.status === 'authenticated' && res.auth?.token) {
stopPolling()
await handleLoginSuccess(res.auth.token)
return
}
if (['failed', 'expired', 'cancelled', 'error'].includes(res.status)) {
await redirectToLoginError('failed', 'Autenticazione CIE non completata. Riprova dal login.')
return
}
if (attempts >= maxAttempts) {
await redirectToLoginError('timeout', 'Tempo di attesa scaduto durante la verifica CIE. Riprova.')
return
}
statusMessage.value = 'Autenticazione completata sul provider. Attendo conferma finale da Visione...'
scheduleNextPoll()
} catch (err: any) {
await redirectToLoginError('verification_error', err.data?.message || 'Errore durante la verifica della sessione CIE.')
}
}
onMounted(() => {
checkSession()
})
onBeforeUnmount(() => {
stopPolling()
})
</script>
<template>
<div class="d-flex align-items-center bg-light py-5">
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-md-8 col-lg-6">
<div class="card card-bg shadow-sm">
<div class="card-body p-4 p-md-5 text-center">
<BIIcon name="it-card" size="xl" color="primary" class="mb-3" />
<h1 class="h3 font-weight-bold mb-3">Accesso con CIE</h1>
<div v-if="isLoading" class="py-3">
<div class="spinner-border text-primary mb-3" role="status">
<span class="visually-hidden">Caricamento...</span>
</div>
<p class="text-muted mb-0">{{ statusMessage }}</p>
</div>
<div v-else-if="errorMessage" class="py-2">
<div class="alert alert-danger text-start mb-4" role="alert">
{{ errorMessage }}
</div>
<button class="btn btn-primary" @click="router.push('/auth/login')">
Torna al login
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>