Newer
Older
bugtrail / packages / web / src / stores / auth.ts
import { computed, ref } from "vue";
import type { User } from "@ltt/shared";
import * as api from "../api";

const SESSION_KEY = "ltt.user";

const user = ref<User | null>(loadCached());
const loading = ref(false);

function loadCached(): User | null {
  try {
    const raw = localStorage.getItem(SESSION_KEY);
    return raw ? (JSON.parse(raw) as User) : null;
  } catch {
    return null;
  }
}

function set(next: User | null) {
  user.value = next;
  try {
    if (next) localStorage.setItem(SESSION_KEY, JSON.stringify(next));
    else localStorage.removeItem(SESSION_KEY);
  } catch {
    /* storage may be unavailable — session cookie is the source of truth */
  }
}

export function useAuth() {
  const isAuthenticated = computed(() => user.value !== null);

  async function fetch() {
    loading.value = true;
    try {
      set(await api.me());
    } catch {
      set(null);
    } finally {
      loading.value = false;
    }
  }

  async function login(email: string, password: string) {
    set(await api.login(email, password));
  }

  async function register(nickname: string, email: string, password: string) {
    set(await api.register(nickname, email, password));
  }

  async function logout() {
    try {
      await api.logout();
    } finally {
      set(null);
    }
  }

  function clear() {
    set(null);
  }

  return { user, loading, isAuthenticated, fetch, login, register, logout, clear };
}