Newer
Older
smart-home-server / webclient / src / stores / auth.js
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 || [];
        await refreshToken();
      } 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 = `/proxy.php?path=/auth/login&return_to=${encodeURIComponent(returnTo)}`;
  }

  return {
    user,
    permissions,
    isLoading,
    isAuthenticated,
    hasPermission,
    hasAnyPermission,
    init,
    refreshToken,
    logout,
    redirectToLogin,
  };
});