Описание изменений

This commit is contained in:
2025-03-20 12:06:03 +03:00
parent 9d2a829cd6
commit fe9783e814
17 changed files with 131 additions and 620 deletions

View File

@@ -17,7 +17,6 @@
"buffer": "^6.0.3",
"connect-pg-simple": "^10.0.0",
"ethers": "6.13.5",
"pinia": "^2.0.33",
"siwe": "^2.1.4",
"sortablejs": "^1.15.6",
"vue": "^3.2.47",

View File

@@ -5,29 +5,60 @@
</template>
<script setup>
import { onMounted } from 'vue';
import { useAuthStore } from './stores/auth';
import { onMounted, ref, provide, computed } from 'vue';
import { useRouter } from 'vue-router';
import axios from 'axios';
console.log('App.vue: Version with auth check loaded');
const authStore = useAuthStore();
const router = useRouter();
async function checkAuth() {
try {
const response = await axios.get('/api/auth/check');
if (response.data.authenticated) {
authStore.setAuth(response.data);
}
} catch (error) {
console.error('Error checking auth:', error);
}
}
// Создаем реактивное состояние с помощью ref
const authState = ref({
isAuthenticated: false,
userRole: null,
address: null
});
onMounted(checkAuth);
// Предоставляем состояние аутентификации всем компонентам
const auth = {
// Используем computed для реактивности
isAuthenticated: computed(() => authState.value.isAuthenticated),
userRole: computed(() => authState.value.userRole),
address: computed(() => authState.value.address),
async checkAuth() {
try {
const response = await axios.get('/api/auth/check');
console.log('Auth check response:', response.data);
authState.value = {
isAuthenticated: response.data.authenticated,
userRole: response.data.role,
address: response.data.address
};
console.log('Auth state updated:', authState.value);
} catch (error) {
console.error('Auth check failed:', error);
}
},
async disconnect() {
try {
await axios.post('/api/auth/logout');
authState.value = {
isAuthenticated: false,
userRole: null,
address: null
};
} catch (error) {
console.error('Logout failed:', error);
}
}
};
provide('auth', auth);
onMounted(async () => {
await auth.checkAuth();
});
</script>
<style>

View File

@@ -1,9 +1,8 @@
import axios from 'axios';
import { useAuthStore } from '../stores/auth';
// Создаем экземпляр axios с базовым URL
const api = axios.create({
baseURL: '', // Убираем baseURL
baseURL: import.meta.env.VITE_API_URL || '',
withCredentials: true,
headers: {
'Content-Type': 'application/json'
@@ -15,10 +14,6 @@ api.interceptors.request.use(
(config) => {
config.withCredentials = true; // Важно для каждого запроса
const authStore = useAuthStore();
if (authStore.isAuthenticated && authStore.address) {
config.headers.Authorization = `Bearer ${authStore.address}`;
}
return config;
},
(error) => Promise.reject(error)
@@ -30,15 +25,11 @@ api.interceptors.response.use(
console.log('Response from server:', response.data);
return response;
},
(error) => {
async (error) => {
// Проверяем, что это действительно ошибка авторизации
if (error.response?.status === 401 &&
!error.config.url.includes('/auth/') &&
!error.config.url.includes('/verify') &&
!error.config.url.includes('/chat/history')) { // Не очищаем при ошибке загрузки истории
console.log('Auth error, clearing state');
const auth = useAuthStore();
auth.disconnect();
if (error.response?.status === 401) {
// Перенаправляем на страницу логина
window.location.href = '/login';
}
return Promise.reject(error);
}

View File

@@ -1,5 +1,5 @@
<template>
<div v-if="authStore.isAuthenticated">
<div v-if="isAuthenticated">
<div class="conversation-list">
<div class="list-header">
<h3>Диалоги</h3>
@@ -40,20 +40,20 @@
</template>
<script setup>
import { ref, onMounted, computed, defineEmits, watch } from 'vue';
import { useAuthStore } from '../../stores/auth';
import { ref, onMounted, computed, defineEmits, watch, inject } from 'vue';
import axios from 'axios';
const emit = defineEmits(['select-conversation']);
const authStore = useAuthStore();
const auth = inject('auth');
const isAuthenticated = computed(() => auth.isAuthenticated.value);
const conversations = ref([]);
const loading = ref(true);
const selectedConversationId = ref(null);
// Следим за изменением статуса аутентификации
watch(() => authStore.isAuthenticated, (isAuthenticated) => {
if (!isAuthenticated) {
watch(() => isAuthenticated.value, (authenticated) => {
if (!authenticated) {
conversations.value = []; // Очищаем список бесед при отключении
selectedConversationId.value = null;
}

View File

@@ -1,5 +1,5 @@
<template>
<div v-if="authStore.isAuthenticated">
<div v-if="isAuthenticated">
<div class="message-thread" ref="threadContainer">
<div v-if="loading" class="loading">Загрузка сообщений...</div>
@@ -28,7 +28,6 @@
<script setup>
import { ref, onMounted, watch, nextTick, defineExpose } from 'vue';
import axios from 'axios';
import { useAuthStore } from '@/stores/auth'
const props = defineProps({
conversationId: {
@@ -40,7 +39,7 @@ const props = defineProps({
const messages = ref([]);
const loading = ref(true);
const threadContainer = ref(null);
const authStore = useAuthStore()
const isAuthenticated = ref(false);
// Загрузка сообщений диалога
const fetchMessages = async () => {
@@ -112,8 +111,8 @@ watch(
);
// Следим за изменением статуса аутентификации
watch(() => authStore.isAuthenticated, (isAuthenticated) => {
if (!isAuthenticated) {
watch(() => isAuthenticated.value, (authenticated) => {
if (!authenticated) {
messages.value = []; // Очищаем сообщения при отключении
}
});

View File

@@ -36,6 +36,7 @@
<script setup>
import { ref, computed } from 'vue';
import axios from 'axios';
const props = defineProps({
onEmailAuth: {
@@ -49,6 +50,7 @@ const code = ref('');
const error = ref('');
const isLoading = ref(false);
const showVerification = ref(false);
const isConnecting = ref(false);
const isValidEmail = computed(() => {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.value);

View File

@@ -18,6 +18,7 @@ import axios from 'axios';
const loading = ref(false);
const error = ref('');
const success = ref('');
const isConnecting = ref(false);
async function connectTelegram() {
try {

View File

@@ -5,14 +5,17 @@
:disabled="isLoading"
class="wallet-btn"
>
{{ isAuthenticated ? 'Подключено' : 'Подключить кошелек' }}
{{ isConnected ? 'Подключено' : 'Подключить кошелек' }}
</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { ref, inject, computed } from 'vue';
import { connectWithWallet } from '../../services/wallet';
import { ethers } from 'ethers';
import { SiweMessage } from 'siwe';
import axios from 'axios';
// Определяем props
const props = defineProps({
@@ -24,6 +27,12 @@ const props = defineProps({
// Определяем состояние
const isLoading = ref(false);
const auth = inject('auth');
const isConnecting = ref(false);
const address = ref('');
// Вычисляемое свойство для статуса подключения
const isConnected = computed(() => auth.isAuthenticated.value);
const emit = defineEmits(['connect']);
@@ -33,22 +42,10 @@ const connectWallet = async () => {
try {
isLoading.value = true;
// Получаем адрес кошелька
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
const address = accounts[0];
// Получаем nonce
const nonceResponse = await api.get(`/api/auth/nonce?address=${address}`);
const nonce = nonceResponse.data.nonce;
// Подписываем сообщение
const message = `${window.location.host} wants you to sign in with your Ethereum account:\n${address.slice(0, 42)}...`;
const signature = await window.ethereum.request({
method: 'personal_sign',
params: [message, address]
});
emit('connect', { address, signature, message });
const result = await connectWithWallet();
await auth.checkAuth();
console.log('Wallet connected, auth state:', auth.isAuthenticated.value);
emit('connect', result);
} catch (error) {
console.error('Error connecting wallet:', error);
} finally {

View File

@@ -2,20 +2,17 @@ import { Buffer } from 'buffer';
globalThis.Buffer = Buffer;
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import router from './router';
import axios from 'axios';
// Настройка axios
axios.defaults.baseURL = ''; // Пустой baseURL, так как мы используем прокси
axios.defaults.withCredentials = true; // Важно для работы с сессиями
axios.defaults.baseURL = import.meta.env.VITE_API_URL || '';
axios.defaults.withCredentials = true;
// Создаем и монтируем приложение Vue
const app = createApp(App);
const pinia = createPinia();
app.use(pinia);
app.use(router);
// Не используем заглушки, так как сервер работает
@@ -29,7 +26,7 @@ app.use(router);
// }
console.log('API URL:', import.meta.env.VITE_API_URL);
console.log('main.js: Starting application with router and Pinia');
console.log('main.js: Starting application with router');
app.mount('#app');
console.log('main.js: Application with router and Pinia mounted');
console.log('main.js: Application with router mounted');

View File

@@ -1,6 +1,6 @@
import { createRouter, createWebHistory } from 'vue-router';
import HomeView from '../views/HomeView.vue';
import { useAuthStore } from '../stores/auth';
import axios from 'axios';
console.log('router/index.js: Script loaded');
@@ -21,8 +21,6 @@ console.log('router/index.js: Router created');
// Защита маршрутов
router.beforeEach(async (to, from, next) => {
const authStore = useAuthStore();
// Если пытаемся перейти на несуществующий маршрут, перенаправляем на главную
if (!to.matched.length) {
return next({ name: 'home' });
@@ -30,17 +28,19 @@ router.beforeEach(async (to, from, next) => {
// Проверяем аутентификацию, если маршрут требует авторизации
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!authStore.isAuthenticated) {
return next({ name: 'home' });
}
// Проверяем права администратора
if (to.matched.some(record => record.meta.requiresAdmin) && !authStore.isAdmin) {
return next({ name: 'home' });
try {
const response = await axios.get('/api/auth/check');
if (response.data.authenticated) {
next();
} else {
next('/login');
}
} catch (error) {
next('/login');
}
} else {
next();
}
next();
});
export default router;

View File

@@ -1,6 +1,5 @@
import { ethers } from 'ethers';
import api from '../api/axios';
import { useAuthStore } from '../stores/auth';
import axios from 'axios';
export async function connectWithWallet() {
try {
@@ -24,7 +23,7 @@ export async function connectWithWallet() {
console.log('Normalized address:', address);
console.log('Requesting nonce...');
const { data: { nonce } } = await api.get('/api/auth/nonce', {
const { data: { nonce } } = await axios.get('/api/auth/nonce', {
params: { address }
});
console.log('Got nonce:', nonce);
@@ -58,19 +57,17 @@ export async function connectWithWallet() {
console.log('Got signature:', signature);
console.log('Sending verification request...');
const response = await api.post('/api/auth/verify', {
const response = await axios.post('/api/auth/verify', {
address,
signature,
message
});
console.log('Verification response:', response.data);
const authStore = useAuthStore();
if (response.data.authenticated) {
authStore.setAuth(response.data);
}
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
return response.data;
return { address, signer };
} catch (error) {
// Форматируем ошибку для пользователя
const message = error.message || 'Ошибка подключения кошелька';

View File

@@ -1,515 +0,0 @@
import { defineStore } from 'pinia';
import axios from '../api/axios';
export const useAuthStore = defineStore('auth', {
state: () => ({
user: null,
isAuthenticated: false,
isAdmin: false,
authType: null,
identities: {},
loading: false,
error: null,
messages: [],
address: null,
wallet: null,
telegramId: null,
email: null,
userId: null
}),
actions: {
async connectWallet(address, signature, message) {
this.loading = true;
this.error = null;
try {
const response = await axios.post('/api/chat/verify', {
address,
signature,
message
}, {
withCredentials: true
});
this.user = {
id: response.data.userId,
address: address
};
this.isAuthenticated = response.data.authenticated;
this.isAdmin = response.data.isAdmin;
this.authType = 'wallet';
// Сохраняем адрес кошелька в локальном хранилище
console.log('Saving wallet address to localStorage:', address);
localStorage.setItem('walletAddress', address);
// Связываем гостевые сообщения с аутентифицированным пользователем
try {
await axios.post('/api/chat/link-guest-messages');
console.log('Guest messages linked to authenticated user');
} catch (linkError) {
console.error('Error linking guest messages:', linkError);
}
return {
success: true,
authenticated: response.data.authenticated,
address: address,
isAdmin: response.data.isAdmin,
authType: response.data.authType
};
} catch (error) {
this.error = error.response?.data?.error || 'Ошибка подключения кошелька';
return { success: false, error: this.error };
} finally {
this.loading = false;
}
},
async connectTelegram(telegramData) {
this.loading = true;
this.error = null;
try {
const response = await axios.post('/api/auth/telegram', telegramData);
this.user = {
id: response.data.userId,
telegramId: telegramData.telegramId
};
this.isAuthenticated = response.data.authenticated;
this.isAdmin = response.data.isAdmin;
this.authType = response.data.authType;
this.identities = response.data.identities || {};
return true;
} catch (error) {
this.error = error.response?.data?.error || 'Ошибка подключения Telegram';
return false;
} finally {
this.loading = false;
}
},
async connectEmail(email, verificationCode) {
this.loading = true;
this.error = null;
try {
const response = await axios.post('/api/auth/email', {
email, verificationCode
});
this.user = {
id: response.data.userId,
email
};
this.isAuthenticated = response.data.authenticated;
this.isAdmin = response.data.isAdmin;
this.authType = response.data.authType;
this.identities = response.data.identities || {};
return true;
} catch (error) {
this.error = error.response?.data?.error || 'Ошибка подключения Email';
return false;
} finally {
this.loading = false;
}
},
async linkIdentity(identityType, identityValue) {
this.loading = true;
this.error = null;
try {
const response = await axios.post('/api/auth/link-identity', {
identityType, identityValue
});
this.identities = response.data.identities;
this.isAdmin = response.data.isAdmin;
return true;
} catch (error) {
this.error = error.response?.data?.error || 'Ошибка связывания аккаунта';
return false;
} finally {
this.loading = false;
}
},
async logout() {
try {
await axios.post('/api/auth/logout');
this.user = null;
this.isAuthenticated = false;
this.isAdmin = false;
this.authType = null;
this.identities = {};
this.messages = [];
this.address = null;
// Удаляем адрес из localStorage
localStorage.removeItem('walletAddress');
} catch (error) {
console.error('Ошибка при выходе:', error);
}
},
async checkAuth() {
try {
console.log('Checking auth state...');
const response = await axios.get('/api/auth/check');
console.log('Auth check response:', response.data);
if (response.data.authenticated) {
this.isAuthenticated = true;
this.user = {
id: response.data.userId,
address: response.data.address
};
this.address = response.data.address;
this.isAdmin = response.data.isAdmin;
this.authType = response.data.authType;
return {
authenticated: true,
user: this.user,
address: response.data.address,
isAdmin: response.data.isAdmin,
authType: response.data.authType
};
} else {
this.isAuthenticated = false;
this.user = null;
this.address = null;
this.isAdmin = false;
this.authType = null;
return { authenticated: false };
}
} catch (error) {
console.error('Error checking auth:', error);
this.isAuthenticated = false;
this.user = null;
this.address = null;
this.isAdmin = false;
this.authType = null;
return { authenticated: false };
}
},
async refreshSession() {
try {
// Если есть адрес в localStorage, используем его
const storedAddress = localStorage.getItem('walletAddress');
const response = await axios.post('/api/auth/refresh-session', {
address: storedAddress || this.address
}, {
withCredentials: true
});
return response.data.success;
} catch (error) {
console.error('Error refreshing session:', error);
return false;
}
},
async checkWalletConnection() {
// Проверяем, есть ли сохраненный адрес кошелька
const savedAddress = localStorage.getItem('walletAddress');
console.log('Checking for saved wallet address:', savedAddress);
if (savedAddress) {
try {
// Проверяем, доступен ли провайдер Ethereum (MetaMask)
if (window.ethereum) {
// Запрашиваем доступ к аккаунтам
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
const currentAddress = accounts[0].toLowerCase();
console.log('Current connected address:', currentAddress);
console.log('Saved address:', savedAddress.toLowerCase());
// Проверяем, совпадает ли текущий адрес с сохраненным
if (currentAddress === savedAddress.toLowerCase()) {
console.log('Wallet address matches, restoring session');
// Восстанавливаем состояние аутентификации
this.user = {
id: null, // ID будет получен при проверке аутентификации
address: savedAddress
};
// Проверяем аутентификацию на сервере
const authResult = await this.checkAuth();
if (authResult.authenticated) {
console.log('Session restored successfully');
return true;
}
} else {
console.log('Connected wallet address does not match saved address');
localStorage.removeItem('walletAddress');
}
}
} catch (error) {
console.error('Error restoring wallet connection:', error);
}
}
return false;
},
async requestEmailVerification(email) {
this.loading = true;
this.error = null;
try {
const response = await axios.post('/api/auth/email/request', { email });
console.log('Email verification code response:', response.data);
return {
success: true,
message: response.data.message,
verificationCode: response.data.verificationCode // Для разработки
};
} catch (error) {
this.error = error.response?.data?.error || 'Ошибка запроса кода';
return { success: false, error: this.error };
} finally {
this.loading = false;
}
},
async verifyEmail(code) {
this.loading = true;
this.error = null;
try {
const response = await axios.post('/api/auth/email/verify', { code });
if (response.data.success) {
this.isAuthenticated = true;
this.user = {
id: response.data.userId,
email: response.data.email
};
if (response.data.walletAddress) {
this.user.address = response.data.walletAddress;
this.address = response.data.walletAddress;
}
this.isAdmin = response.data.isAdmin;
this.authType = 'email';
}
return response.data;
} catch (error) {
this.error = error.response?.data?.error || 'Ошибка верификации';
return { success: false, error: this.error };
} finally {
this.loading = false;
}
},
async requestTelegramCode() {
this.loading = true;
this.error = null;
try {
const response = await axios.get('/api/auth/telegram/code');
return response.data;
} catch (error) {
this.error = error.response?.data?.error || 'Ошибка запроса кода';
return { success: false, error: this.error };
} finally {
this.loading = false;
}
},
async verifyTelegram(telegramId, code) {
this.loading = true;
this.error = null;
try {
const response = await axios.post('/api/auth/telegram/verify', { telegramId, code });
if (response.data.success) {
this.isAuthenticated = true;
this.user = {
id: response.data.userId,
telegramId: response.data.telegramId
};
if (response.data.walletAddress) {
this.user.address = response.data.walletAddress;
this.address = response.data.walletAddress;
}
this.isAdmin = response.data.isAdmin;
this.authType = 'telegram';
}
return response.data;
} catch (error) {
this.error = error.response?.data?.error || 'Ошибка верификации';
return { success: false, error: this.error };
} finally {
this.loading = false;
}
},
async linkIdentity(type, value) {
this.loading = true;
this.error = null;
try {
const response = await axios.post('/api/auth/link-identity', { type, value });
if (response.data.success) {
if (type === 'wallet') {
this.user.address = value;
this.address = value;
} else if (type === 'email') {
this.user.email = value;
} else if (type === 'telegram') {
this.user.telegramId = value;
}
this.isAdmin = response.data.isAdmin;
}
return response.data;
} catch (error) {
this.error = error.response?.data?.error || 'Ошибка связывания аккаунта';
return { success: false, error: this.error };
} finally {
this.loading = false;
}
},
async createTelegramAuthToken() {
this.loading = true;
this.error = null;
try {
const response = await axios.post('/api/auth/telegram/auth-token');
return response.data;
} catch (error) {
this.error = error.response?.data?.error || 'Ошибка создания токена';
return { success: false, error: this.error };
} finally {
this.loading = false;
}
},
async checkTelegramAuthStatus(token) {
try {
const response = await axios.get(`/api/auth/telegram/auth-status/${token}`);
if (response.data.success && response.data.authenticated) {
// Обновляем состояние аутентификации
await this.checkAuth();
}
return response.data;
} catch (error) {
console.error('Error checking Telegram auth status:', error);
return { success: false, error: 'Ошибка проверки статуса' };
}
},
async disconnect() {
try {
// Очищаем сессию на сервере
await axios.post('/api/auth/clear-session');
// Очищаем состояние
this.isAuthenticated = false;
this.userId = null;
this.address = null;
this.isAdmin = false;
this.authType = null;
// Очищаем локальное хранилище
localStorage.removeItem('auth');
} catch (error) {
console.error('Error during disconnect:', error);
}
},
// Выносим очистку состояния в отдельный метод
clearState() {
this.isAuthenticated = false;
this.wallet = null;
this.messages = [];
this.user = null;
this.address = null;
this.isAdmin = false;
this.authType = null;
this.identities = {};
this.telegramId = null;
this.userId = null;
// Очищаем локальное хранилище
localStorage.removeItem('wallet');
localStorage.removeItem('isAuthenticated');
localStorage.removeItem('walletAddress');
localStorage.removeItem('auth');
},
async setWalletAuth(authData) {
this.isAuthenticated = authData.authenticated;
this.address = authData.address;
this.isAdmin = authData.isAdmin;
},
async setTelegramAuth(authData) {
this.telegramId = authData.telegramId;
// Проверяем баланс токенов если есть подключенный кошелек
if (this.address) {
await this.checkTokenBalance();
}
},
async checkTokenBalance() {
try {
const response = await axios.get(`/api/auth/check-tokens?address=${this.address}`);
this.isAdmin = response.data.isAdmin;
} catch (error) {
console.error('Error checking token balance:', error);
}
},
setAuth(authData) {
console.log('Setting auth state:', authData);
// Обновляем только состояние в памяти
this.isAuthenticated = authData.authenticated || authData.isAuthenticated;
this.user = {
id: authData.userId,
address: authData.address
};
this.userId = authData.userId;
this.isAdmin = authData.isAdmin;
this.authType = authData.authType;
this.address = authData.address;
console.log('Auth state updated:', {
isAuthenticated: this.isAuthenticated,
userId: this.userId,
authType: this.authType,
address: this.address,
isAdmin: this.isAdmin
});
}
}
});

View File

@@ -2,7 +2,7 @@
<div class="home">
<h1> HB3 - Accelerator DLE (Digital Legal Entity - DAO Fork)</h1>
<div class="auth-section" v-if="!auth.isAuthenticated">
<div class="auth-section" v-if="!isAuthenticated">
<h3>Венчурный фонд и поставщик программного обеспечения</h3>
</div>
@@ -10,13 +10,13 @@
<div class="chat-container">
<div class="chat-header">
<!-- Используем тот же компонент, что и в сообщениях -->
<div v-if="!auth.isAuthenticated" class="auth-buttons">
<div v-if="!isAuthenticated" class="auth-buttons">
<button class="auth-btn wallet-btn" @click="handleWalletAuth">
<span class="auth-icon">👛</span> Подключить кошелек
</button>
</div>
<div v-else class="wallet-info">
<span>{{ truncateAddress(auth.address) }}</span>
<span>{{ truncateAddress(auth.address.value) }}</span>
<button class="disconnect-btn" @click="disconnectWallet">
Отключить кошелек
</button>
@@ -24,7 +24,7 @@
</div>
<!-- Кнопка загрузки предыдущих сообщений -->
<div v-if="auth.isAuthenticated && hasMoreMessages" class="load-more">
<div v-if="isAuthenticated && hasMoreMessages" class="load-more">
<button @click="loadMoreMessages" :disabled="isLoadingMore">
{{ isLoadingMore ? 'Загрузка...' : 'Показать предыдущие сообщения' }}
</button>
@@ -40,7 +40,7 @@
</div>
<!-- Кнопки аутентификации -->
<div v-if="message.showAuthButtons && !auth.isAuthenticated" class="auth-buttons">
<div v-if="message.showAuthButtons && !isAuthenticated" class="auth-buttons">
<button class="auth-btn wallet-btn" @click="handleWalletAuth">
<span class="auth-icon">👛</span> Подключить кошелек
</button>
@@ -117,16 +117,18 @@
</template>
<script setup>
import { ref, computed, onMounted, watch, nextTick, onBeforeUnmount } from 'vue';
import { useAuthStore } from '../stores/auth';
import { ref, computed, onMounted, watch, nextTick, onBeforeUnmount, inject } from 'vue';
import WalletConnection from '../components/identity/WalletConnection.vue';
import TelegramConnect from '../components/identity/TelegramConnect.vue';
import EmailConnect from '../components/identity/EmailConnect.vue';
import api from '../api/axios';
import { connectWithWallet } from '../services/wallet';
console.log('HomeView.vue: Version with chat loaded');
const auth = useAuthStore();
const auth = inject('auth');
const isAuthenticated = computed(() => auth.isAuthenticated.value);
const authType = ref(null);
const messages = ref([]);
const guestMessages = ref([]);
const newMessage = ref('');
@@ -181,7 +183,7 @@ const scrollToBottom = () => {
// Загрузка сообщений
const loadMoreMessages = async () => {
if (!auth.isAuthenticated) return;
if (!isAuthenticated.value) return;
try {
isLoadingMore.value = true;
@@ -213,7 +215,7 @@ const loadMoreMessages = async () => {
};
// Загружаем сообщения при изменении аутентификации
watch(() => auth.isAuthenticated, async (newValue) => {
watch(() => isAuthenticated.value, async (newValue) => {
if (newValue) {
messages.value = [];
offset.value = 0;
@@ -244,12 +246,13 @@ watch(() => auth.isAuthenticated, async (newValue) => {
}
});
// Функция для подключения кошелька
// Находим существующую функцию handleWalletAuth и обновляем её
const handleWalletAuth = async () => {
try {
const result = await connectWithWallet();
await auth.checkAuth();
if (result.success) {
if (result.authenticated) {
// Сохраняем гостевые сообщения перед очисткой
const guestMessages = [...messages.value];
messages.value = [];
@@ -432,7 +435,7 @@ const handleMessage = async (text) => {
newMessage.value = '';
isLoading.value = true;
if (!auth.isAuthenticated) {
if (!isAuthenticated.value) {
// Сохраняем в таблицу guest_messages
const response = await api.post('/api/chat/guest-message', {
message: messageContent,

View File

@@ -38,10 +38,10 @@ export default defineConfig({
},
server: {
port: 5173,
host: 'localhost',
host: '127.0.0.1',
proxy: {
'/api': {
target: 'http://localhost:8000',
target: 'http://127.0.0.1:8000',
changeOrigin: true,
secure: false,
credentials: true,