Files
frontend/src/stores/auth.ts

118 lines
3.3 KiB
TypeScript

import { defineStore } from "pinia";
import { ref, computed } from "vue";
import { registerUser as apiRegisterUser, loginUser as apiLoginUser } from "@/api/auth";
import { getUserProfile as apiGetUserProfile } from "@/api/user";
import type { RegisterRequest, User, LoginRequest } from "@/types";
import router from "@/router";
import apiClient from "@/api/axios";
export const useAuthStore = defineStore("auth", () => {
// State
const user = ref<User | null>(null);
const token = ref<string | null>(localStorage.getItem("authToken"));
const skinUrl = ref<string | null>(null);
const isLoading = ref(false);
const error = ref<string | null>(null);
// === Getters ===
const isAuthenticated = computed(() => !!user.value && !!token.value);
// Actions
async function fetchUserProfile() {
if (!user.value) return;
try {
const response = await apiGetUserProfile(user.value.uuid);
if (response.data && response.data.properties) {
const textureProp = response.data.properties.find((p) => p.name === "textures");
if (textureProp) {
const textureData = JSON.parse(atob(textureProp.value));
if (textureData.textures?.SKIN?.url) {
skinUrl.value = textureData.textures.SKIN.url;
} else {
skinUrl.value = null;
}
}
}
} catch (e) {
console.error("Failed to fetch user profile:", e);
skinUrl.value = null;
}
}
function setAuthData(userData: User, authToken: string) {
user.value = userData;
token.value = authToken;
localStorage.setItem("authToken", authToken);
apiClient.defaults.headers.common["Authorization"] = `Bearer ${authToken}`;
fetchUserProfile();
}
async function handleLogin(credentials: LoginRequest) {
isLoading.value = true;
error.value = null;
try {
const response = await apiLoginUser(credentials);
setAuthData(response.data.user, response.data.token);
await router.push({ name: "home" });
} catch (e: any) {
if (e.response && e.response.data) {
error.value = e.response.data;
} else {
error.value = "Произошла неизвестная ошибка при входе";
}
} finally {
isLoading.value = false;
}
}
async function handleRegister(userData: RegisterRequest) {
isLoading.value = true;
error.value = null;
try {
await apiRegisterUser(userData);
await router.push({ name: "login" });
} catch (e: any) {
if (e.response && e.response.data) {
error.value = e.response.data;
} else {
error.value = "Произошла неизвестная ошибка";
}
} finally {
isLoading.value = false;
}
}
// Функция для выхода
function handleLogout() {
user.value = null;
token.value = null;
skinUrl.value = null;
localStorage.removeItem("authToken");
delete apiClient.defaults.headers.common["Authorization"];
router.push({ name: "login" });
}
async function checkAuth() {
if (token.value) {
if (user.value) {
await fetchUserProfile();
}
}
}
return {
// State
user,
token,
skinUrl,
isLoading,
error,
// Getters
isAuthenticated,
// Actions
handleLogin,
handleRegister,
handleLogout,
fetchUserProfile,
checkAuth,
};
});