import { computed, ref } from "vue"; import { defineStore } from "pinia"; import apiClient from "@/api/client"; import type { AuthenticatedUser, LoginResponse } from "@/types"; const USER_STORAGE_KEY = "live-recorder-user"; const TOKEN_STORAGE_KEY = "live-recorder-token"; function readStoredValue(key: string) { return localStorage.getItem(key) ?? sessionStorage.getItem(key); } function clearStoredSession() { [localStorage, sessionStorage].forEach((storage) => { storage.removeItem(TOKEN_STORAGE_KEY); storage.removeItem(USER_STORAGE_KEY); }); } export const useAuthStore = defineStore("auth", () => { const token = ref(readStoredValue(TOKEN_STORAGE_KEY) ?? ""); const user = ref( (() => { const raw = readStoredValue(USER_STORAGE_KEY); return raw ? (JSON.parse(raw) as AuthenticatedUser) : null; })() ); const isAuthenticated = computed(() => Boolean(token.value)); function persistSession(session: LoginResponse, rememberMe: boolean) { token.value = session.token; user.value = session.user; clearStoredSession(); const storage = rememberMe ? localStorage : sessionStorage; storage.setItem(TOKEN_STORAGE_KEY, session.token); storage.setItem(USER_STORAGE_KEY, JSON.stringify(session.user)); } function clearSession() { token.value = ""; user.value = null; clearStoredSession(); } async function login(username: string, password: string, rememberMe: boolean) { const { data } = await apiClient.post("/auth/login", { username, password, rememberMe }); persistSession(data, rememberMe); return data; } async function logout() { try { await apiClient.post("/auth/logout"); } finally { clearSession(); } } async function changePassword(currentPassword: string, newPassword: string) { await apiClient.post("/auth/change-password", { currentPassword, newPassword }); clearSession(); } return { token, user, isAuthenticated, login, logout, changePassword, clearSession }; });