Files
SIB/frontend/src/stores/auth.ts

118 lines
3.9 KiB
TypeScript

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { supabase } from '@/supabase'
export const useAuthStore = defineStore('auth', () => {
const userSession = ref<any>(null)
const userProfile = ref<any>(null)
const isAuthenticated = computed(() => !!userSession.value)
// We check the custom Postgres role we put in our `users` table
const role = computed(() => userProfile.value?.role || userSession.value?.user?.user_metadata?.role)
const userName = computed(() => userProfile.value?.full_name || userSession.value?.user?.user_metadata?.full_name)
const isAdmin = computed(() => role.value?.toUpperCase() === 'ADMIN')
const isDriver = computed(() => role.value?.toUpperCase() === 'DRIVER')
const isPromoter = computed(() => role.value?.toUpperCase() === 'PROMOTER')
const isPassenger = computed(() => !role.value || role.value?.toUpperCase() === 'PASSENGER')
/** Listens for Supabase Auth state changes */
supabase.auth.onAuthStateChange(async (_event, session) => {
userSession.value = session
if (session?.user) {
// Immediately fetch their role from standard Public table if present
const { data } = await supabase
.from('users')
.select('*')
.eq('id', session.user.id)
.single()
if (data) userProfile.value = data
} else {
userProfile.value = null
}
})
async function login(email: string, pass: string) {
const { data, error } = await supabase.auth.signInWithPassword({ email, password: pass })
if (error) throw new Error(error.message)
if (data.user) {
// Rol disponible al instante desde el JWT — sin consultas BD bloqueantes
userSession.value = data.session
userProfile.value = {
id: data.user.id,
email: data.user.email,
full_name: data.user.user_metadata?.full_name || data.user.email,
role: data.user.user_metadata?.role || 'PASSENGER'
}
}
}
async function register(email: string, pass: string, fullName: string) {
console.log('Realizando signUp en Supabase...')
const { data, error } = await supabase.auth.signUp({
email,
password: pass,
options: {
data: {
full_name: fullName,
role: 'PASSENGER'
}
}
})
if (error) throw new Error(error.message)
// Supabase retorna sesión inmediata si auto-confirm está activado.
if (data.session && data.user) {
userSession.value = data.session
userProfile.value = {
id: data.user.id,
email: data.user.email,
full_name: data.user.user_metadata?.full_name || data.user.email,
role: data.user.user_metadata?.role || 'PASSENGER'
}
}
}
function logout() {
// Limpiar estado de Pinia inmediatamente
userSession.value = null
userProfile.value = null
// Limpiar TODA la sesión del navegador sin esperar a Supabase
localStorage.clear()
sessionStorage.clear()
// Limpiar IndexedDB donde Supabase guarda tokens
try {
indexedDB.deleteDatabase('supabase-js-auth')
indexedDB.deleteDatabase('supabase')
} catch (_) { }
// Llamar signOut en background (sin await - no bloqueamos)
supabase.auth.signOut().catch(() => { })
// Redirigir forzando recarga completa del navegador
window.location.replace('/login')
}
return {
userSession,
userProfile,
role,
userName,
isAuthenticated,
isAdmin,
isDriver,
isPromoter,
isPassenger,
login,
register,
logout
}
})