import { computed, ref } from 'vue' import { defineStore } from 'pinia' import { AUTH_EXPIRED_EVENT, AUTH_UPDATED_EVENT, apiRequest, clearAccessToken, refreshSession, setAccessToken, } from '@/lib/api' import type { AuthResponse, AuthUser } from '@/types/api' import type { Profile } from '@/types/database' export const useAuthStore = defineStore('auth', () => { const user = ref(null) const profile = ref(null) const loading = ref(true) let listenersAttached = false const isLoggedIn = computed(() => !!user.value) const isAdmin = computed(() => profile.value?.role === 'admin') function applyAuth(auth: AuthResponse) { setAccessToken(auth.access_token) user.value = auth.user profile.value = { id: auth.user.id, username: auth.user.username, avatar_url: auth.user.avatar_url, role: auth.user.role, is_disabled: auth.user.is_disabled, created_at: auth.user.created_at, } } function clearAuth() { clearAccessToken() user.value = null profile.value = null } async function login(email: string, password: string) { const auth = await apiRequest('/auth/login', { method: 'POST', auth: false, body: { email, password }, }) applyAuth(auth) } async function register(email: string, password: string, username: string) { await apiRequest('/auth/register', { method: 'POST', auth: false, body: { email, password, username }, }) } async function logout() { try { await apiRequest('/auth/logout', { method: 'POST', retry: false }) } finally { clearAuth() } } async function updateUsername(username: string) { const updatedUser = await apiRequest('/profiles/me', { method: 'PATCH', body: { username }, }) user.value = updatedUser profile.value = { id: updatedUser.id, username: updatedUser.username, avatar_url: updatedUser.avatar_url, role: updatedUser.role, is_disabled: updatedUser.is_disabled, created_at: updatedUser.created_at, } } async function updatePassword(password: string) { const auth = await apiRequest('/auth/password', { method: 'PATCH', body: { password }, }) applyAuth(auth) } async function sendPasswordReset(email: string) { await apiRequest('/auth/forgot-password', { method: 'POST', auth: false, body: { email }, }) } async function initialize() { if (!listenersAttached) { window.addEventListener(AUTH_UPDATED_EVENT, event => { applyAuth((event as CustomEvent).detail) }) window.addEventListener(AUTH_EXPIRED_EVENT, clearAuth) listenersAttached = true } try { applyAuth(await refreshSession()) } catch { clearAuth() } finally { loading.value = false } } return { user, profile, loading, isLoggedIn, isAdmin, login, register, logout, updateUsername, updatePassword, sendPasswordReset, initialize, } })