import { computed, ref } from 'vue' import { defineStore } from 'pinia' import { getCurrentUserApi, loginApi } from '../services/auth' import { hasAnyPermission, hasPermission } from '../services/access' import type { CurrentUser } from '../types/auth' const TOKEN_KEY = 'teapot-system-token' const USER_KEY = 'teapot-system-user' function readUserFromStorage() { const raw = window.localStorage.getItem(USER_KEY) if (!raw) { return null } try { return JSON.parse(raw) as CurrentUser } catch { return null } } export const useAuthStore = defineStore('auth', () => { const token = ref(window.localStorage.getItem(TOKEN_KEY) ?? '') const user = ref(readUserFromStorage()) const initialized = ref(false) const isAuthenticated = computed(() => Boolean(token.value && user.value)) function persistSession() { if (token.value) { window.localStorage.setItem(TOKEN_KEY, token.value) } else { window.localStorage.removeItem(TOKEN_KEY) } if (user.value) { window.localStorage.setItem(USER_KEY, JSON.stringify(user.value)) } else { window.localStorage.removeItem(USER_KEY) } } async function login(username: string, password: string) { const payload = await loginApi({ username, password }) token.value = payload.token user.value = payload.user initialized.value = true persistSession() } async function bootstrap() { if (!token.value) { initialized.value = true return } try { user.value = await getCurrentUserApi(token.value) } catch { token.value = '' user.value = null persistSession() } finally { initialized.value = true } } function logout() { token.value = '' user.value = null initialized.value = true persistSession() } function can(permission: string) { return hasPermission(user.value, permission) } function canAny(permissions: string[]) { return hasAnyPermission(user.value, permissions) } return { token, user, initialized, isAuthenticated, login, bootstrap, logout, can, canAny, } })