import { ref, computed } from "vue";
import { defineStore } from "pinia";
import { apiGet, apiPost } from "../api/client";
import { setAccessToken, clearAccessToken } from "../api/auth";
export const useAuthStore = defineStore("auth", () => {
const user = ref(null);
const permissions = ref([]);
const isLoading = ref(false);
const isAuthenticated = computed(() => !!user.value);
const permissionSet = computed(() => new Set(permissions.value));
function hasPermission(slug) {
return permissionSet.value.has(slug);
}
function hasAnyPermission(slugs) {
if (!Array.isArray(slugs)) {
return false;
}
return slugs.some((s) => permissionSet.value.has(s));
}
async function init() {
isLoading.value = true;
try {
const result = await apiGet("/auth/me");
if (result.ok) {
const payload = result.data?.data || {};
user.value = payload.user || null;
permissions.value = payload.permissions || [];
} else {
user.value = null;
permissions.value = [];
clearAccessToken();
}
} catch {
user.value = null;
permissions.value = [];
clearAccessToken();
} finally {
isLoading.value = false;
}
}
async function refreshToken() {
const result = await apiPost("/auth/refresh");
if (result.ok) {
setAccessToken(result.data?.data?.access_token || null);
} else {
clearAccessToken();
}
}
async function logout() {
try {
await apiPost("/auth/logout");
} catch {
// ignore network errors during logout
}
user.value = null;
permissions.value = [];
clearAccessToken();
window.location.href = "/#/login";
}
function redirectToLogin() {
const returnTo = window.location.href;
window.location.href = `/auth/login?return_to=${encodeURIComponent(returnTo)}`;
}
return {
user,
permissions,
isLoading,
isAuthenticated,
hasPermission,
hasAnyPermission,
init,
refreshToken,
logout,
redirectToLogin,
};
});