add storage

This commit is contained in:
2026-07-18 16:16:10 +07:00
parent ad68ccc297
commit 0731123fbb
7 changed files with 375 additions and 23 deletions
+226
View File
@@ -0,0 +1,226 @@
// stores/auth.ts
import { type User } from '@/api/generated/crabs/evening_detective_server';
import { buildClient, getURL } from '@/api/generated/crabs/evening_detective_server/client';
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
export const useAuthStore = defineStore('auth', () => {
// ===== STATE =====
const accessToken = ref<string | null>(null);
const refreshToken = ref<string | null>(null);
const user = ref<User | null>(null);
const isLoading = ref(false);
const error = ref<string | null>(null);
// ===== GETTERS =====
const isAuthenticated = computed(() => !!accessToken.value);
const username = computed(() => user.value?.username || '');
const userRoles = computed(() => user.value?.roles || []);
// ===== ACTIONS =====
// Инициализация из localStorage при загрузке
function initFromStorage() {
const token = localStorage.getItem('accessToken');
const refresh = localStorage.getItem('refreshToken');
if (token) {
accessToken.value = token;
refreshToken.value = refresh;
// Получаем данные пользователя
fetchUser();
}
}
function getToken(): string | null {
return accessToken.value
}
// Получение данных пользователя
async function fetchUser() {
if (!accessToken.value) return;
try {
const client = buildClient(getToken);
const response = await client.GetMe({});
if (response.error) {
error.value = response.error;
return;
}
if (response.user) {
user.value = response.user;
}
} catch (err) {
console.error('Failed to fetch user:', err);
// Если 401 — токен протух
if (err instanceof Error && err.message.includes('401')) {
await logout();
}
}
}
// Логин
async function login(email: string, password: string) {
isLoading.value = true;
error.value = null;
try {
const client = buildClient(getToken);
const response = await client.Login({ email, password });
if (response.error) {
error.value = response.error;
return false;
}
// Сохраняем токены
if (response.accessToken) {
accessToken.value = response.accessToken;
refreshToken.value = response.refreshToken || null;
// Сохраняем в localStorage
localStorage.setItem('accessToken', response.accessToken);
if (response.refreshToken) {
localStorage.setItem('refreshToken', response.refreshToken);
}
// Получаем данные пользователя
await fetchUser();
return true;
}
return false;
} catch (err) {
error.value = err instanceof Error ? err.message : 'Login failed';
return false;
} finally {
isLoading.value = false;
}
}
// Обновление токена
async function refreshTokenAction() {
if (!refreshToken.value) return false;
try {
const client = buildClient(getToken);
const response = await client.Refresh({
refreshToken: refreshToken.value
});
if (response.error || !response.accessToken) {
return false;
}
// Обновляем токены
accessToken.value = response.accessToken;
refreshToken.value = response.refreshToken || null;
localStorage.setItem('accessToken', response.accessToken);
if (response.refreshToken) {
localStorage.setItem('refreshToken', response.refreshToken);
}
return true;
} catch {
return false;
}
}
// Регистрация
async function signup(username: string, email: string) {
isLoading.value = true;
error.value = null;
try {
const client = buildClient(getToken);
const response = await client.Signup({ username, email });
if (response.error) {
error.value = response.error;
return false;
}
return true
} catch (err) {
error.value = err instanceof Error ? err.message : 'Signup failed';
return false;
} finally {
isLoading.value = false;
}
}
// Восстановление пароля
async function refreshPassword(email: string) {
isLoading.value = true;
error.value = null;
try {
const client = buildClient(getToken);
const response = await client.RefreshPassword({ email });
if (response.error) {
error.value = response.error;
return false;
}
return true;
} catch (err) {
error.value = err instanceof Error ? err.message : 'Password reset failed';
return false;
} finally {
isLoading.value = false;
}
}
// Выход
async function logout() {
accessToken.value = null;
refreshToken.value = null;
user.value = null;
error.value = null;
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
}
// Проверка ролей
function hasRole(role: string): boolean {
return userRoles.value.includes(role);
}
function hasAnyRole(roles: string[]): boolean {
return roles.some(role => userRoles.value.includes(role));
}
// ===== RETURN =====
return {
// State
accessToken,
refreshToken,
user,
isLoading,
error,
// Getters
isAuthenticated,
username,
userRoles,
// Actions
initFromStorage,
getToken,
login,
signup,
refreshPassword,
logout,
fetchUser,
refreshTokenAction,
hasRole,
hasAnyRole,
};
});