118 lines
3.9 KiB
TypeScript
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
|
|
}
|
|
})
|