ваше сообщение коммита
This commit is contained in:
@@ -41,7 +41,7 @@ class AIAssistant {
|
||||
this.baseUrl = process.env.OLLAMA_BASE_URL || 'http://localhost:11434';
|
||||
this.defaultModel = process.env.OLLAMA_MODEL || 'qwen2.5:7b';
|
||||
this.lastHealthCheck = 0;
|
||||
this.healthCheckInterval = 30000; // 30 секунд
|
||||
this.healthCheckInterval = 300000; // 5 минут (увеличено с 30 секунд для уменьшения логов)
|
||||
|
||||
// Создаем экземпляр AIQueue
|
||||
this.aiQueue = new AIQueue();
|
||||
@@ -114,8 +114,6 @@ class AIAssistant {
|
||||
try {
|
||||
const { message, history, systemPrompt, rules } = request;
|
||||
|
||||
logger.info(`[AIAssistant] Обрабатываю запрос: message="${message?.substring(0, 50)}...", history=${history?.length || 0}, systemPrompt="${systemPrompt?.substring(0, 50)}..."`);
|
||||
|
||||
// Используем прямой запрос к API, а не getResponse (чтобы избежать цикла)
|
||||
const result = await this.directRequest(
|
||||
[{ role: 'user', content: message }],
|
||||
@@ -123,8 +121,6 @@ class AIAssistant {
|
||||
{ temperature: 0.3, maxTokens: 150 }
|
||||
);
|
||||
|
||||
logger.info(`[AIAssistant] Запрос успешно обработан, результат: "${result?.substring(0, 100)}..."`);
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
logger.error(`[AIAssistant] Ошибка в processQueueRequest:`, error.message);
|
||||
|
||||
@@ -125,12 +125,10 @@ class AIQueue extends EventEmitter {
|
||||
// Пауза/возобновление очереди
|
||||
pause() {
|
||||
this.isPaused = true;
|
||||
logger.info('[AIQueue] Очередь приостановлена');
|
||||
}
|
||||
|
||||
resume() {
|
||||
this.isPaused = false;
|
||||
logger.info('[AIQueue] Очередь возобновлена');
|
||||
}
|
||||
|
||||
// Проверка статуса паузы
|
||||
|
||||
210
backend/services/databaseConnectionManager.js
Normal file
210
backend/services/databaseConnectionManager.js
Normal file
@@ -0,0 +1,210 @@
|
||||
/**
|
||||
* Сервис для динамического управления подключениями к базе данных
|
||||
* Позволяет изменять настройки БД без перезапуска приложения
|
||||
*/
|
||||
|
||||
const { Pool } = require('pg');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
class DatabaseConnectionManager {
|
||||
constructor() {
|
||||
this.currentPool = null;
|
||||
this.currentConfig = null;
|
||||
this.connectionListeners = [];
|
||||
this.isReconnecting = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализация с дефолтными настройками
|
||||
*/
|
||||
async initialize() {
|
||||
try {
|
||||
// Загружаем текущие настройки из БД
|
||||
const dbSettingsService = require('./dbSettingsService');
|
||||
const settings = await dbSettingsService.getSettings();
|
||||
|
||||
if (settings) {
|
||||
await this.updateConnection(settings);
|
||||
} else {
|
||||
// Используем дефолтные настройки из переменных окружения
|
||||
await this.updateConnection({
|
||||
db_host: process.env.DB_HOST || 'postgres',
|
||||
db_port: parseInt(process.env.DB_PORT) || 5432,
|
||||
db_name: process.env.DB_NAME || 'dapp_db',
|
||||
db_user: process.env.DB_USER || 'dapp_user',
|
||||
db_password: process.env.DB_PASSWORD || 'dapp_password'
|
||||
});
|
||||
}
|
||||
|
||||
logger.info('[DatabaseConnectionManager] Инициализация завершена');
|
||||
} catch (error) {
|
||||
logger.error('[DatabaseConnectionManager] Ошибка инициализации:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновление подключения к БД
|
||||
*/
|
||||
async updateConnection(newConfig) {
|
||||
try {
|
||||
logger.info('[DatabaseConnectionManager] Обновление подключения к БД...');
|
||||
|
||||
// Проверяем, изменились ли настройки
|
||||
if (this.currentConfig && this.configsEqual(this.currentConfig, newConfig)) {
|
||||
logger.info('[DatabaseConnectionManager] Настройки не изменились, обновление не требуется');
|
||||
return;
|
||||
}
|
||||
|
||||
// Создаем новое подключение
|
||||
const newPool = this.createPool(newConfig);
|
||||
|
||||
// Тестируем новое подключение
|
||||
await this.testConnection(newPool);
|
||||
|
||||
// Закрываем старое подключение
|
||||
if (this.currentPool) {
|
||||
await this.closePool(this.currentPool);
|
||||
}
|
||||
|
||||
// Обновляем текущие настройки
|
||||
this.currentPool = newPool;
|
||||
this.currentConfig = { ...newConfig };
|
||||
|
||||
logger.info('[DatabaseConnectionManager] Подключение к БД успешно обновлено');
|
||||
|
||||
// Уведомляем слушателей об изменении
|
||||
this.notifyConnectionChange();
|
||||
|
||||
} catch (error) {
|
||||
logger.error('[DatabaseConnectionManager] Ошибка обновления подключения:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Создание пула подключений
|
||||
*/
|
||||
createPool(config) {
|
||||
return new Pool({
|
||||
host: config.db_host,
|
||||
port: config.db_port,
|
||||
database: config.db_name,
|
||||
user: config.db_user,
|
||||
password: config.db_password,
|
||||
ssl: false,
|
||||
max: 10,
|
||||
min: 0,
|
||||
idleTimeoutMillis: 30000,
|
||||
connectionTimeoutMillis: 2000,
|
||||
maxUses: 7500,
|
||||
allowExitOnIdle: true,
|
||||
maxLifetimeSeconds: 0
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Тестирование подключения
|
||||
*/
|
||||
async testConnection(pool) {
|
||||
const client = await pool.connect();
|
||||
try {
|
||||
await client.query('SELECT 1');
|
||||
logger.info('[DatabaseConnectionManager] Тест подключения успешен');
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Закрытие пула подключений
|
||||
*/
|
||||
async closePool(pool) {
|
||||
try {
|
||||
await pool.end();
|
||||
logger.info('[DatabaseConnectionManager] Старый пул подключений закрыт');
|
||||
} catch (error) {
|
||||
logger.warn('[DatabaseConnectionManager] Ошибка при закрытии пула:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение текущего пула подключений
|
||||
*/
|
||||
getCurrentPool() {
|
||||
return this.currentPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение текущих настроек
|
||||
*/
|
||||
getCurrentConfig() {
|
||||
return this.currentConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Сравнение конфигураций
|
||||
*/
|
||||
configsEqual(config1, config2) {
|
||||
return (
|
||||
config1.db_host === config2.db_host &&
|
||||
config1.db_port === config2.db_port &&
|
||||
config1.db_name === config2.db_name &&
|
||||
config1.db_user === config2.db_user &&
|
||||
config1.db_password === config2.db_password
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавление слушателя изменений подключения
|
||||
*/
|
||||
addConnectionChangeListener(listener) {
|
||||
this.connectionListeners.push(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Уведомление слушателей об изменении подключения
|
||||
*/
|
||||
notifyConnectionChange() {
|
||||
this.connectionListeners.forEach(listener => {
|
||||
try {
|
||||
listener(this.currentConfig);
|
||||
} catch (error) {
|
||||
logger.error('[DatabaseConnectionManager] Ошибка в слушателе:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Принудительное переподключение
|
||||
*/
|
||||
async reconnect() {
|
||||
if (this.isReconnecting) {
|
||||
logger.warn('[DatabaseConnectionManager] Переподключение уже выполняется');
|
||||
return;
|
||||
}
|
||||
|
||||
this.isReconnecting = true;
|
||||
try {
|
||||
if (this.currentConfig) {
|
||||
await this.updateConnection(this.currentConfig);
|
||||
}
|
||||
} finally {
|
||||
this.isReconnecting = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение статуса подключения
|
||||
*/
|
||||
getConnectionStatus() {
|
||||
return {
|
||||
isConnected: !!this.currentPool,
|
||||
config: this.currentConfig,
|
||||
isReconnecting: this.isReconnecting,
|
||||
listenersCount: this.connectionListeners.length
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new DatabaseConnectionManager();
|
||||
@@ -11,30 +11,83 @@
|
||||
*/
|
||||
|
||||
const encryptedDb = require('./encryptedDatabaseService');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
class DbSettingsService {
|
||||
constructor() {
|
||||
this.connectionManager = null;
|
||||
this.initialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализация сервиса
|
||||
*/
|
||||
async initialize() {
|
||||
if (this.initialized) return;
|
||||
|
||||
try {
|
||||
// Динамически импортируем менеджер подключений
|
||||
this.connectionManager = require('./databaseConnectionManager');
|
||||
await this.connectionManager.initialize();
|
||||
this.initialized = true;
|
||||
logger.info('[DbSettingsService] Сервис инициализирован');
|
||||
} catch (error) {
|
||||
logger.error('[DbSettingsService] Ошибка инициализации:', error);
|
||||
// Не прерываем выполнение, сервис будет работать без динамического обновления
|
||||
}
|
||||
}
|
||||
|
||||
async getSettings() {
|
||||
const rows = await encryptedDb.getData('db_settings', { id: 1 }, 1);
|
||||
return rows[0];
|
||||
}
|
||||
|
||||
async upsertSettings({ db_host, db_port, db_name, db_user, db_password }) {
|
||||
const data = {
|
||||
id: 1,
|
||||
db_host,
|
||||
db_port,
|
||||
db_name,
|
||||
db_user,
|
||||
db_password,
|
||||
updated_at: new Date()
|
||||
};
|
||||
try {
|
||||
const data = {
|
||||
id: 1,
|
||||
db_host,
|
||||
db_port,
|
||||
db_name,
|
||||
db_user,
|
||||
db_password,
|
||||
updated_at: new Date()
|
||||
};
|
||||
|
||||
// Пытаемся обновить существующую запись
|
||||
const existing = await this.getSettings();
|
||||
if (existing) {
|
||||
return await encryptedDb.saveData('db_settings', data, { id: 1 });
|
||||
} else {
|
||||
return await encryptedDb.saveData('db_settings', data);
|
||||
// Пытаемся обновить существующую запись
|
||||
const existing = await this.getSettings();
|
||||
let result;
|
||||
|
||||
if (existing) {
|
||||
result = await encryptedDb.saveData('db_settings', data, { id: 1 });
|
||||
} else {
|
||||
result = await encryptedDb.saveData('db_settings', data);
|
||||
}
|
||||
|
||||
// После успешного сохранения обновляем подключение к БД
|
||||
if (this.connectionManager && this.initialized) {
|
||||
try {
|
||||
await this.connectionManager.updateConnection({
|
||||
db_host,
|
||||
db_port,
|
||||
db_name,
|
||||
db_user,
|
||||
db_password
|
||||
});
|
||||
|
||||
logger.info('[DbSettingsService] Настройки БД обновлены и подключение переустановлено');
|
||||
} catch (connectionError) {
|
||||
logger.error('[DbSettingsService] Ошибка обновления подключения к БД:', connectionError);
|
||||
// Не прерываем выполнение, только логируем ошибку
|
||||
}
|
||||
} else {
|
||||
logger.warn('[DbSettingsService] Менеджер подключений не инициализирован, перезапустите приложение для применения изменений');
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
logger.error('[DbSettingsService] Ошибка сохранения настроек БД:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +97,42 @@ class DbSettingsService {
|
||||
getEncryptionStatus() {
|
||||
return encryptedDb.getEncryptionStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить статус подключения к БД
|
||||
*/
|
||||
getConnectionStatus() {
|
||||
if (this.connectionManager && this.initialized) {
|
||||
return this.connectionManager.getConnectionStatus();
|
||||
}
|
||||
return {
|
||||
isConnected: false,
|
||||
config: null,
|
||||
isReconnecting: false,
|
||||
listenersCount: 0,
|
||||
error: 'Менеджер подключений не инициализирован'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Принудительное переподключение к БД
|
||||
*/
|
||||
async reconnect() {
|
||||
if (!this.connectionManager || !this.initialized) {
|
||||
throw new Error('Менеджер подключений не инициализирован');
|
||||
}
|
||||
|
||||
try {
|
||||
// Переподключаемся к БД с новыми настройками
|
||||
await this.connectionManager.reconnect();
|
||||
|
||||
// logger.info('[DbSettingsService] Переподключение к БД выполнено'); // Убрано избыточное логирование
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
logger.error('[DbSettingsService] Ошибка переподключения к БД:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new DbSettingsService();
|
||||
@@ -192,14 +192,29 @@ class DLEV2Service {
|
||||
createdAt: new Date().toISOString()
|
||||
};
|
||||
|
||||
logger.info('Данные DLE для сохранения:', JSON.stringify(dleData, null, 2));
|
||||
|
||||
// logger.info('Данные DLE для сохранения:', JSON.stringify(dleData, null, 2)); // Убрано избыточное логирование
|
||||
|
||||
if (dleData.dleAddress) {
|
||||
// Сохраняем одну карточку DLE с информацией о всех сетях
|
||||
const savedPath = this.saveDLEData(dleData);
|
||||
logger.info(`DLE данные сохранены в: ${savedPath}`);
|
||||
// Сохраняем данные DLE в файл
|
||||
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
||||
const fileName = `dle-v2-${timestamp}.json`;
|
||||
const savedPath = path.join(__dirname, '../contracts-data/dles', fileName);
|
||||
|
||||
// Создаем директорию, если её нет
|
||||
const dlesDir = path.dirname(savedPath);
|
||||
if (!fs.existsSync(dlesDir)) {
|
||||
fs.mkdirSync(dlesDir, { recursive: true });
|
||||
}
|
||||
|
||||
fs.writeFileSync(savedPath, JSON.stringify(dleData, null, 2));
|
||||
// logger.info(`DLE данные сохранены в: ${savedPath}`); // Убрано избыточное логирование
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: dleData
|
||||
};
|
||||
} else {
|
||||
logger.error('Не удалось получить адрес DLE из результата деплоя');
|
||||
throw new Error('DLE адрес не получен после деплоя');
|
||||
}
|
||||
} catch (e) {
|
||||
logger.warn('Не удалось сохранить локальную карточку DLE:', e.message);
|
||||
|
||||
@@ -126,7 +126,7 @@ class EmailBotService {
|
||||
authTimeout: 60000, // Таймаут на аутентификацию - 60 секунд
|
||||
greetingTimeout: 30000, // Таймаут на приветствие сервера
|
||||
socketTimeout: 60000, // Таймаут на операции сокета
|
||||
debug: console.log // Включаем отладку для диагностики
|
||||
debug: false // Включаем отладку для диагностики
|
||||
};
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ class EmailBotService {
|
||||
html: `<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;"><h2 style="color: #333;">Код подтверждения</h2><p style="font-size: 16px; color: #666;">Ваш код подтверждения:</p><div style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; text-align: center; margin: 20px 0;"><span style="font-size: 24px; font-weight: bold; color: #333;">${code}</span></div><p style="font-size: 14px; color: #999;">Код действителен в течение 15 минут.</p></div>`,
|
||||
};
|
||||
await transporter.sendMail(mailOptions);
|
||||
logger.info(`Verification code sent to ${email}`);
|
||||
// logger.info(`Verification code sent to ${email}`); // Убрано логирование email адреса
|
||||
} catch (error) {
|
||||
logger.error('Error sending verification code:', error);
|
||||
throw error;
|
||||
@@ -192,7 +192,7 @@ class EmailBotService {
|
||||
}
|
||||
|
||||
if (!results || results.length === 0) {
|
||||
logger.info('No messages found');
|
||||
// logger.info('No messages found'); // Убрано избыточное логирование
|
||||
this.imap.end();
|
||||
return;
|
||||
}
|
||||
@@ -229,7 +229,7 @@ class EmailBotService {
|
||||
processedCount++;
|
||||
if (processedCount >= totalMessages) {
|
||||
if (unreadMessages.length === 0) {
|
||||
logger.info('No unread messages found');
|
||||
// logger.info('No unread messages found'); // Убрано избыточное логирование
|
||||
}
|
||||
this.imap.end();
|
||||
}
|
||||
@@ -249,7 +249,8 @@ class EmailBotService {
|
||||
// Проверяем, что сообщение непрочитанное (нет флага \Seen)
|
||||
const isUnread = !flags.includes('\\Seen');
|
||||
|
||||
logger.info(`[EmailBot] Проверяем письмо: UID=${uid}, Message-ID=${messageId}, From=${fromEmail}, Unread=${isUnread}`);
|
||||
// Логируем только для отладки
|
||||
// logger.info(`[EmailBot] Проверяем письмо: UID=${uid}, Message-ID=${messageId}, From=${fromEmail}, Unread=${isUnread}`); // Убрано избыточное логирование
|
||||
|
||||
// Обрабатываем ВСЕ новые письма, независимо от статуса "прочитано"
|
||||
// Проверка на уже обработанные письма будет в processIncomingEmail
|
||||
@@ -271,12 +272,13 @@ class EmailBotService {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info(`[EmailBot] Найдено ${unreadMessages.length} непрочитанных сообщений`);
|
||||
// logger.info(`[EmailBot] Найдено ${unreadMessages.length} непрочитанных сообщений`); // Убрано избыточное логирование
|
||||
|
||||
// Обрабатываем каждое непрочитанное сообщение
|
||||
for (const messageData of unreadMessages) {
|
||||
for (const message of unreadMessages) {
|
||||
// logger.info(`[EmailBot] Обрабатываем письмо: UID=${message.uid}, Message-ID=${message.messageId}, From=${message.fromEmail}`); // Убрано избыточное логирование
|
||||
try {
|
||||
await this.processIncomingEmail(messageData);
|
||||
await this.processIncomingEmail(message);
|
||||
} catch (processErr) {
|
||||
logger.error('Error processing incoming email:', processErr);
|
||||
}
|
||||
@@ -350,28 +352,13 @@ class EmailBotService {
|
||||
}
|
||||
|
||||
// Проверяем, не обрабатывали ли мы уже это письмо
|
||||
if (messageId) {
|
||||
// Проверка дубликатов на основе Message-ID
|
||||
try {
|
||||
const existingMessage = await encryptedDb.getData(
|
||||
'messages',
|
||||
{
|
||||
user_id: userId,
|
||||
channel: 'email',
|
||||
direction: 'in',
|
||||
message_id: messageId
|
||||
},
|
||||
1
|
||||
);
|
||||
|
||||
if (existingMessage.length > 0) {
|
||||
logger.info(`[EmailBot] Игнорируем дубликат письма от ${fromEmail} (Message-ID: ${messageId})`);
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(`[EmailBot] Ошибка при проверке дубликатов: ${error.message}`);
|
||||
// Продолжаем обработку в случае ошибки
|
||||
}
|
||||
const existingResponse = await encryptedDb.getData('ai_responses', {
|
||||
message_id: messageId
|
||||
});
|
||||
|
||||
if (existingResponse.length > 0) {
|
||||
// logger.info(`[EmailBot] Игнорируем дубликат письма от ${fromEmail} (Message-ID: ${messageId})`); // Убрано логирование email адреса
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверяем, не обрабатывали ли мы уже это письмо (улучшенная проверка)
|
||||
@@ -624,7 +611,7 @@ class EmailBotService {
|
||||
};
|
||||
|
||||
await transporter.sendMail(mailOptions);
|
||||
logger.info(`Email sent to ${to} (attempt ${attempt})`);
|
||||
// logger.info(`Email sent to ${to} (attempt ${attempt})`); // Убрано логирование email адреса
|
||||
|
||||
// Закрываем соединение после успешной отправки
|
||||
transporter.close();
|
||||
|
||||
@@ -323,8 +323,6 @@ class EncryptedDataService {
|
||||
*/
|
||||
async deleteData(tableName, conditions) {
|
||||
try {
|
||||
console.log(`[EncryptedDataService] deleteData: tableName=${tableName}, conditions=`, conditions);
|
||||
|
||||
// Проверяем, включено ли шифрование
|
||||
if (!this.isEncryptionEnabled) {
|
||||
return await this.executeUnencryptedQuery(tableName, conditions);
|
||||
@@ -339,8 +337,6 @@ class EncryptedDataService {
|
||||
ORDER BY ordinal_position
|
||||
`, [tableName]);
|
||||
|
||||
console.log(`[EncryptedDataService] Columns for ${tableName}:`, columns.map(c => c.column_name));
|
||||
|
||||
// Функция для заключения зарезервированных слов в кавычки
|
||||
const quoteReservedWord = (word) => {
|
||||
const reservedWords = ['order', 'group', 'user', 'index', 'table', 'column', 'key', 'foreign', 'primary', 'unique', 'check', 'constraint', 'default', 'null', 'not', 'and', 'or', 'as', 'on', 'in', 'is', 'like', 'between', 'exists', 'all', 'any', 'some', 'distinct', 'case', 'when', 'then', 'else', 'end', 'limit', 'offset', 'having', 'union', 'intersect', 'except', 'with', 'recursive'];
|
||||
@@ -383,9 +379,6 @@ class EncryptedDataService {
|
||||
params.unshift(this.encryptionKey);
|
||||
}
|
||||
|
||||
console.log(`[EncryptedDataService] DELETE query: ${query}`);
|
||||
console.log(`[EncryptedDataService] DELETE params:`, params);
|
||||
|
||||
const result = await db.getQuery()(query, params);
|
||||
return result.rows;
|
||||
} catch (error) {
|
||||
|
||||
@@ -165,20 +165,18 @@ class IdentityService {
|
||||
} catch (error) {
|
||||
logger.error(`[IdentityService] Error getting identities for user ${userId}:`, error);
|
||||
|
||||
// Если произошла ошибка расшифровки, попробуем получить данные напрямую
|
||||
try {
|
||||
logger.info(`[IdentityService] Trying to get unencrypted data for user ${userId}`);
|
||||
const { rows } = await db.getQuery()(
|
||||
'SELECT id, user_id, created_at, provider_encrypted as provider, provider_id_encrypted as provider_id FROM user_identities WHERE user_id = $1',
|
||||
[userId]
|
||||
);
|
||||
|
||||
logger.info(`[IdentityService] Found ${rows.length} unencrypted identities for user ${userId}`);
|
||||
return rows;
|
||||
} catch (fallbackError) {
|
||||
logger.error(`[IdentityService] Fallback error getting identities for user ${userId}:`, fallbackError);
|
||||
return [];
|
||||
}
|
||||
// Если не удалось получить данные через encryptedDb, пробуем через обычный запрос
|
||||
// logger.info(`[IdentityService] Trying to get unencrypted data for user ${userId}`); // Убрано избыточное логирование
|
||||
|
||||
const { rows } = await db.getQuery()(`
|
||||
SELECT provider, provider_id, provider_username, provider_avatar, created_at, updated_at
|
||||
FROM user_identities
|
||||
WHERE user_id = $1
|
||||
ORDER BY created_at DESC
|
||||
`, [userId]);
|
||||
|
||||
// logger.info(`[IdentityService] Found ${rows.length} unencrypted identities for user ${userId}`); // Убрано избыточное логирование
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -138,15 +138,15 @@ class VerificationService {
|
||||
// Очистка истекших кодов
|
||||
async cleanupExpiredCodes() {
|
||||
try {
|
||||
const expiredCodes = await encryptedDb.getData('verification_codes', {
|
||||
expires_at: { $lt: new Date() }
|
||||
});
|
||||
|
||||
for (const code of expiredCodes) {
|
||||
await encryptedDb.deleteData('verification_codes', { id: code.id });
|
||||
// Удаляем истекшие коды
|
||||
const expiredCodes = await encryptedDb.getData('verification_codes', { expires_at: { $lt: new Date() } });
|
||||
|
||||
if (expiredCodes.length > 0) {
|
||||
for (const expiredCode of expiredCodes) {
|
||||
await encryptedDb.deleteData('verification_codes', { id: expiredCode.id });
|
||||
}
|
||||
// logger.info(`Cleaned up ${expiredCodes.length} expired verification codes`); // Убрано избыточное логирование
|
||||
}
|
||||
|
||||
logger.info(`Cleaned up ${expiredCodes.length} expired verification codes`);
|
||||
} catch (error) {
|
||||
logger.error('Error cleaning up expired codes:', error);
|
||||
}
|
||||
|
||||
@@ -15,15 +15,12 @@ const logger = require('../utils/logger');
|
||||
|
||||
// Получение связанного кошелька
|
||||
async function getLinkedWallet(userId) {
|
||||
logger.info(`[getLinkedWallet] Called with userId: ${userId} (Type: ${typeof userId})`);
|
||||
try {
|
||||
const result = await encryptedDb.getData('user_identities', {
|
||||
user_id: userId,
|
||||
provider: 'wallet'
|
||||
}, 1);
|
||||
logger.info(`[getLinkedWallet] DB query result for userId ${userId}:`, result);
|
||||
const address = result[0]?.provider_id;
|
||||
logger.info(`[getLinkedWallet] Returning address: ${address} for userId ${userId}`);
|
||||
return address;
|
||||
} catch (error) {
|
||||
logger.error(`[getLinkedWallet] Error fetching linked wallet for userId ${userId}:`, error);
|
||||
|
||||
Reference in New Issue
Block a user