ваше сообщение коммита
This commit is contained in:
@@ -26,18 +26,21 @@ app.set('host', '0.0.0.0');
|
||||
app.set('port', process.env.PORT || 8000);
|
||||
|
||||
// Настройка CORS
|
||||
app.use(cors({
|
||||
app.use(
|
||||
cors({
|
||||
origin: [
|
||||
'http://localhost:5173',
|
||||
'http://127.0.0.1:5173' // Добавляем альтернативный origin
|
||||
'http://127.0.0.1:5173', // Добавляем альтернативный origin
|
||||
],
|
||||
credentials: true,
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
||||
allowedHeaders: ['Content-Type', 'Authorization', 'Cookie']
|
||||
}));
|
||||
allowedHeaders: ['Content-Type', 'Authorization', 'Cookie'],
|
||||
})
|
||||
);
|
||||
|
||||
// Настройка сессии
|
||||
app.use(session({
|
||||
app.use(
|
||||
session({
|
||||
store: new pgSession({
|
||||
pool,
|
||||
tableName: 'session',
|
||||
@@ -51,9 +54,10 @@ app.use(session({
|
||||
httpOnly: true,
|
||||
secure: false,
|
||||
sameSite: 'lax',
|
||||
path: '/'
|
||||
}
|
||||
}));
|
||||
path: '/',
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Добавим middleware для проверки сессии
|
||||
app.use(async (req, res, next) => {
|
||||
@@ -62,10 +66,7 @@ app.use(async (req, res, next) => {
|
||||
|
||||
// Проверяем сессию в базе данных
|
||||
if (req.sessionID) {
|
||||
const result = await pool.query(
|
||||
'SELECT sess FROM session WHERE sid = $1',
|
||||
[req.sessionID]
|
||||
);
|
||||
const result = await pool.query('SELECT sess FROM session WHERE sid = $1', [req.sessionID]);
|
||||
console.log('Session from DB:', result.rows[0]?.sess);
|
||||
}
|
||||
|
||||
@@ -80,13 +81,16 @@ app.use(async (req, res, next) => {
|
||||
const token = authHeader.split(' ')[1];
|
||||
try {
|
||||
// Находим пользователя по токену
|
||||
const { rows } = await pool.query(`
|
||||
const { rows } = await pool.query(
|
||||
`
|
||||
SELECT u.id,
|
||||
(u.role = 'admin') as is_admin,
|
||||
u.address
|
||||
FROM users u
|
||||
WHERE u.id = $1
|
||||
`, [token]);
|
||||
`,
|
||||
[token]
|
||||
);
|
||||
|
||||
if (rows.length > 0) {
|
||||
const user = rows[0];
|
||||
@@ -95,7 +99,7 @@ app.use(async (req, res, next) => {
|
||||
req.session.isAdmin = user.is_admin;
|
||||
req.session.authenticated = true;
|
||||
|
||||
await new Promise(resolve => req.session.save(resolve));
|
||||
await new Promise((resolve) => req.session.save(resolve));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking auth header:', error);
|
||||
@@ -110,9 +114,11 @@ app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
|
||||
// Настройка безопасности
|
||||
app.use(helmet({
|
||||
contentSecurityPolicy: false // Отключаем CSP для разработки
|
||||
}));
|
||||
app.use(
|
||||
helmet({
|
||||
contentSecurityPolicy: false, // Отключаем CSP для разработки
|
||||
})
|
||||
);
|
||||
|
||||
// Логирование запросов
|
||||
app.use((req, res, next) => {
|
||||
@@ -164,24 +170,27 @@ app.get('/api/health', async (req, res) => {
|
||||
status: 'ok',
|
||||
timestamp: new Date().toISOString(),
|
||||
database: 'connected',
|
||||
ai: aiStatus
|
||||
ai: aiStatus,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Health check failed:', error);
|
||||
res.status(500).json({
|
||||
status: 'error',
|
||||
error: error.message
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Очистка старых сессий
|
||||
setInterval(async () => {
|
||||
setInterval(
|
||||
async () => {
|
||||
try {
|
||||
await pool.query('DELETE FROM session WHERE expire < NOW()');
|
||||
} catch (error) {
|
||||
console.error('Error cleaning old sessions:', error);
|
||||
}
|
||||
}, 15 * 60 * 1000); // Каждые 15 минут
|
||||
},
|
||||
15 * 60 * 1000
|
||||
); // Каждые 15 минут
|
||||
|
||||
module.exports = { app, nonceStore };
|
||||
|
||||
@@ -16,10 +16,10 @@ const sessionConfig = {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
sameSite: 'lax',
|
||||
path: '/'
|
||||
}
|
||||
path: '/',
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
sessionMiddleware: session(sessionConfig)
|
||||
sessionMiddleware: session(sessionConfig),
|
||||
};
|
||||
@@ -56,10 +56,13 @@ const query = (text, params) => {
|
||||
// Функция для сохранения гостевого сообщения в базе данных
|
||||
async function saveGuestMessageToDatabase(message, language, guestId) {
|
||||
try {
|
||||
await query(`
|
||||
await query(
|
||||
`
|
||||
INSERT INTO guest_messages (guest_id, content, language, created_at)
|
||||
VALUES ($1, $2, $3, NOW())
|
||||
`, [guestId, message, language]);
|
||||
`,
|
||||
[guestId, message, language]
|
||||
);
|
||||
console.log('Гостевое сообщение успешно сохранено:', message);
|
||||
} catch (error) {
|
||||
console.error('Ошибка при сохранении гостевого сообщения:', error);
|
||||
|
||||
@@ -41,8 +41,12 @@ async function initRoles() {
|
||||
|
||||
if (rolesExist.rows[0].count < 2) {
|
||||
// Добавляем недостающие роли
|
||||
const userRoleExists = await pool.query(`SELECT EXISTS (SELECT FROM roles WHERE name = 'user');`);
|
||||
const adminRoleExists = await pool.query(`SELECT EXISTS (SELECT FROM roles WHERE name = 'admin');`);
|
||||
const userRoleExists = await pool.query(
|
||||
`SELECT EXISTS (SELECT FROM roles WHERE name = 'user');`
|
||||
);
|
||||
const adminRoleExists = await pool.query(
|
||||
`SELECT EXISTS (SELECT FROM roles WHERE name = 'admin');`
|
||||
);
|
||||
|
||||
if (!userRoleExists.rows[0].exists) {
|
||||
await pool.query(`
|
||||
@@ -82,13 +86,14 @@ async function initializeDatabase() {
|
||||
const migrationsPath = path.join(__dirname, 'migrations');
|
||||
|
||||
// Получаем все файлы миграций
|
||||
const migrationFiles = fs.readdirSync(migrationsPath)
|
||||
.filter(file => file.endsWith('.sql'))
|
||||
const migrationFiles = fs
|
||||
.readdirSync(migrationsPath)
|
||||
.filter((file) => file.endsWith('.sql'))
|
||||
.sort();
|
||||
|
||||
// Получаем выполненные миграции
|
||||
const { rows } = await pool.query('SELECT name FROM migrations');
|
||||
const executedMigrations = new Set(rows.map(row => row.name));
|
||||
const executedMigrations = new Set(rows.map((row) => row.name));
|
||||
|
||||
// Выполняем только новые миграции
|
||||
for (const file of migrationFiles) {
|
||||
@@ -100,10 +105,7 @@ async function initializeDatabase() {
|
||||
await pool.query(sql);
|
||||
|
||||
// Записываем выполненную миграцию
|
||||
await pool.query(
|
||||
'INSERT INTO migrations (name) VALUES ($1)',
|
||||
[file]
|
||||
);
|
||||
await pool.query('INSERT INTO migrations (name) VALUES ($1)', [file]);
|
||||
|
||||
logger.info(`Migration completed: ${file}`);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
Система идентификации пользователей построена на следующих таблицах:
|
||||
|
||||
1. **users** - Основная таблица пользователей
|
||||
|
||||
- `id SERIAL PRIMARY KEY` - Основной идентификатор пользователя
|
||||
- `status` - Статус пользователя (active, blocked)
|
||||
- `role` - Роль пользователя (user, admin)
|
||||
@@ -14,6 +15,7 @@
|
||||
- Поля `username`, `email` и `address` являются устаревшими и должны быть NULL
|
||||
|
||||
2. **user_identities** - Таблица идентификаторов пользователей
|
||||
|
||||
- `id SERIAL PRIMARY KEY` - Идентификатор записи
|
||||
- `user_id INTEGER REFERENCES users(id)` - Ссылка на пользователя
|
||||
- `provider VARCHAR(50)` - Тип идентификатора (email, wallet, telegram, username)
|
||||
@@ -22,6 +24,7 @@
|
||||
- Ограничение `CHECK (provider IN ('email', 'wallet', 'telegram', 'username'))` - запрещает тип 'guest'
|
||||
|
||||
3. **guest_user_mapping** - Таблица связи гостевых идентификаторов с пользователями
|
||||
|
||||
- `id SERIAL PRIMARY KEY` - Идентификатор записи
|
||||
- `user_id INTEGER REFERENCES users(id)` - Ссылка на пользователя
|
||||
- `guest_id VARCHAR(255)` - Гостевой идентификатор
|
||||
@@ -29,6 +32,7 @@
|
||||
- Уникальный ключ `guest_id`
|
||||
|
||||
4. **messages** - Таблица сообщений
|
||||
|
||||
- `id SERIAL PRIMARY KEY` - Идентификатор сообщения
|
||||
- `conversation_id INTEGER REFERENCES conversations(id)` - Ссылка на диалог
|
||||
- `user_id INTEGER REFERENCES users(id)` - Прямая ссылка на пользователя
|
||||
@@ -56,7 +60,6 @@
|
||||
- Создается запись в таблице `users`
|
||||
- Создается запись в таблице `user_identities` с соответствующим провайдером
|
||||
- Гостевой ID сохраняется в таблице `guest_user_mapping` (не в user_identities)
|
||||
|
||||
2. После аутентификации система автоматически обрабатывает гостевые сообщения:
|
||||
- Вызывается метод `linkGuestMessages`
|
||||
- Создается новый диалог для гостевых сообщений
|
||||
@@ -89,6 +92,7 @@
|
||||
## Обработка ошибок
|
||||
|
||||
1. Если возникает ошибка при обработке гостевых сообщений, система:
|
||||
|
||||
- Логирует ошибку
|
||||
- Продолжает попытки обработки при следующих авторизациях
|
||||
- Не удаляет гостевые сообщения до успешной обработки
|
||||
@@ -98,6 +102,7 @@
|
||||
## Оптимизации
|
||||
|
||||
1. Индексы созданы для всех полей, используемых в запросах:
|
||||
|
||||
- `user_identities(user_id)`
|
||||
- `user_identities(provider, provider_id)`
|
||||
- `guest_user_mapping(guest_id)`
|
||||
@@ -106,6 +111,7 @@
|
||||
- `messages(conversation_id)`
|
||||
|
||||
2. Триггеры автоматически поддерживают целостность данных:
|
||||
|
||||
- Автоматическое заполнение `user_id` в таблице `messages`
|
||||
- Очистка неиспользуемых полей в таблице `users`
|
||||
|
||||
@@ -117,6 +123,7 @@
|
||||
## Функции для диагностики
|
||||
|
||||
1. **verify_migration_017()** - проверяет состояние гостевых идентификаторов
|
||||
|
||||
- `guest_identities_count` - количество гостевых идентификаторов в таблице user_identities
|
||||
- `guest_mapping_count` - количество записей в таблице guest_user_mapping
|
||||
- `missing_mappings` - количество гостевых ID, которые отсутствуют в guest_user_mapping
|
||||
|
||||
@@ -69,6 +69,7 @@ END $$;
|
||||
- `verify_identity_system()` - проверка состояния системы идентификации пользователей
|
||||
|
||||
Пример использования:
|
||||
|
||||
```sql
|
||||
SELECT * FROM verify_identity_system();
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
import globals from 'globals';
|
||||
const globals = require('globals');
|
||||
|
||||
export default [
|
||||
module.exports = [
|
||||
{
|
||||
ignores: ['node_modules/**', 'artifacts/**', 'sessions/**', 'logs/**', 'data/**'],
|
||||
},
|
||||
@@ -8,10 +8,11 @@ export default [
|
||||
files: ['**/*.js'],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2022,
|
||||
sourceType: 'module',
|
||||
sourceType: 'module', // Оставляем module, т.к. ESLint может анализировать ES модули
|
||||
globals: {
|
||||
...globals.node,
|
||||
...globals.es2021,
|
||||
// Для тестов Mocha
|
||||
describe: 'readonly',
|
||||
it: 'readonly',
|
||||
beforeEach: 'readonly',
|
||||
@@ -21,8 +22,8 @@ export default [
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'no-unused-vars': 'off',
|
||||
'no-console': 'off',
|
||||
'no-unused-vars': 'warn', // Лучше warn, чем off
|
||||
'no-console': 'off', // Оставляем off для логов в Node.js
|
||||
'no-undef': 'error',
|
||||
'no-duplicate-imports': 'error',
|
||||
},
|
||||
@@ -7920,3 +7920,578 @@
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T13:51:33.815Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T13:52:15.206Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T13:52:15.210Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T13:52:34.099Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T13:52:34.105Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T13:53:04.292Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T13:53:04.296Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T13:54:15.742Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T13:54:15.746Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T13:55:15.978Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T13:55:15.981Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T13:56:16.276Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T13:56:16.281Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T13:57:14.461Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T13:57:14.468Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T13:58:14.617Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T13:58:14.622Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T13:59:14.424Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T13:59:14.428Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:00:15.127Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:00:15.132Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:01:15.786Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:01:15.789Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:02:15.874Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:02:15.883Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:03:16.140Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:03:16.145Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:04:16.400Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:04:16.403Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:05:14.537Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:05:14.541Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:06:14.778Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:06:14.783Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:07:15.131Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:07:15.136Z"}
|
||||
{"level":"info","message":"POST /api/auth/logout","timestamp":"2025-04-21T14:07:24.527Z"}
|
||||
{"level":"info","message":"Session saved successfully","timestamp":"2025-04-21T14:07:24.547Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:07:24.572Z"}
|
||||
{"level":"info","message":"Session saved successfully","timestamp":"2025-04-21T14:07:24.578Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:15:43.797Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:15:43.819Z"}
|
||||
{"level":"info","message":"POST /api/auth/telegram/init","timestamp":"2025-04-21T14:23:49.891Z"}
|
||||
{"level":"info","message":"Generated verification code: FBRKH5","timestamp":"2025-04-21T14:23:49.892Z"}
|
||||
{"level":"info","message":"Creating verification code for telegram:e50442b5c6fad89fc34176fc078d56f1, userId: null","timestamp":"2025-04-21T14:23:49.892Z"}
|
||||
{"level":"info","message":"Verification code created successfully for telegram:e50442b5c6fad89fc34176fc078d56f1","timestamp":"2025-04-21T14:23:49.900Z"}
|
||||
{"level":"info","message":"[initTelegramAuth] Created verification code for guestId: e50442b5c6fad89fc34176fc078d56f1","timestamp":"2025-04-21T14:23:49.901Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:23:51.775Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:23:53.643Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:23:55.499Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:23:57.546Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:23:59.414Z"}
|
||||
{"level":"info","message":"Starting Telegram auth process for code:","timestamp":"2025-04-21T14:24:01.260Z"}
|
||||
{"level":"info","message":"Using existing user 1 for Telegram account 5155951987","timestamp":"2025-04-21T14:24:01.269Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:24:01.312Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:24:01.320Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:24:01.362Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:24:01.365Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:24:01.390Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:24:01.394Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:24:01.415Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:24:01.483Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:24:05.271Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:24:05.274Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:24:05.335Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=36&limit=30","timestamp":"2025-04-21T14:24:05.410Z"}
|
||||
{"level":"info","message":"POST /api/auth/logout","timestamp":"2025-04-21T14:24:10.741Z"}
|
||||
{"level":"info","message":"Session saved successfully","timestamp":"2025-04-21T14:24:10.762Z"}
|
||||
{"level":"info","message":"GET /api/auth/nonce?address=0xF45aa4917b3775bA37f48Aeb3dc1a943561e9e0B","timestamp":"2025-04-21T14:42:10.379Z"}
|
||||
{"level":"info","message":"Nonce f90108f4ef8e168fc79bc36648d6fd95 сохранен для адреса 0xF45aa4917b3775bA37f48Aeb3dc1a943561e9e0B","timestamp":"2025-04-21T14:42:10.387Z"}
|
||||
{"level":"info","message":"POST /api/auth/verify","timestamp":"2025-04-21T14:42:12.698Z"}
|
||||
{"level":"info","message":"[verify] Verifying signature for address: 0xF45aa4917b3775bA37f48Aeb3dc1a943561e9e0B","timestamp":"2025-04-21T14:42:12.699Z"}
|
||||
{"level":"info","message":"Checking admin role for address: 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","timestamp":"2025-04-21T14:42:12.793Z"}
|
||||
{"address":"0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","balance":"500000.0","contract":"0x4B294265720B09ca39BFBA18c7E368413c0f68eB","hasTokens":true,"level":"info","message":"Token balance on bsc:","timestamp":"2025-04-21T14:42:13.708Z"}
|
||||
{"level":"info","message":"Found admin tokens on bsc","timestamp":"2025-04-21T14:42:13.709Z"}
|
||||
{"address":"0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","balance":"1500000.0","contract":"0xd95a45fc46a7300e6022885afec3d618d7d3f27c","hasTokens":true,"level":"info","message":"Token balance on eth:","timestamp":"2025-04-21T14:42:13.990Z"}
|
||||
{"level":"info","message":"Found admin tokens on eth","timestamp":"2025-04-21T14:42:13.990Z"}
|
||||
{"address":"0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","balance":"499999.9","contract":"0xdce769b847a0a697239777d0b1c7dd33b6012ba0","hasTokens":true,"level":"info","message":"Token balance on arbitrum:","timestamp":"2025-04-21T14:42:13.992Z"}
|
||||
{"level":"info","message":"Found admin tokens on arbitrum","timestamp":"2025-04-21T14:42:13.993Z"}
|
||||
{"address":"0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","balance":"454852.0","contract":"0x351f59de4fedbdf7601f5592b93db3b9330c1c1d","hasTokens":true,"level":"info","message":"Token balance on polygon:","timestamp":"2025-04-21T14:42:16.371Z"}
|
||||
{"level":"info","message":"Found admin tokens on polygon","timestamp":"2025-04-21T14:42:16.372Z"}
|
||||
{"balances":{"arbitrum":"499999.9","bsc":"500000.0","eth":"1500000.0","polygon":"454852.0"},"level":"info","message":"Admin role summary for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b:","networks":["bsc","eth","arbitrum","polygon"],"timestamp":"2025-04-21T14:42:16.372Z"}
|
||||
{"level":"info","message":"Admin role granted for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","timestamp":"2025-04-21T14:42:16.373Z"}
|
||||
{"level":"info","message":"[verify] Found or created user 1 for wallet 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","timestamp":"2025-04-21T14:42:16.373Z"}
|
||||
{"level":"info","message":"Checking admin tokens for address: 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","timestamp":"2025-04-21T14:42:16.373Z"}
|
||||
{"level":"info","message":"Checking admin role for address: 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","timestamp":"2025-04-21T14:42:16.374Z"}
|
||||
{"address":"0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","balance":"500000.0","contract":"0x4B294265720B09ca39BFBA18c7E368413c0f68eB","hasTokens":true,"level":"info","message":"Token balance on bsc:","timestamp":"2025-04-21T14:42:16.662Z"}
|
||||
{"level":"info","message":"Found admin tokens on bsc","timestamp":"2025-04-21T14:42:16.662Z"}
|
||||
{"address":"0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","balance":"1500000.0","contract":"0xd95a45fc46a7300e6022885afec3d618d7d3f27c","hasTokens":true,"level":"info","message":"Token balance on eth:","timestamp":"2025-04-21T14:42:16.788Z"}
|
||||
{"level":"info","message":"Found admin tokens on eth","timestamp":"2025-04-21T14:42:16.789Z"}
|
||||
{"address":"0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","balance":"454852.0","contract":"0x351f59de4fedbdf7601f5592b93db3b9330c1c1d","hasTokens":true,"level":"info","message":"Token balance on polygon:","timestamp":"2025-04-21T14:42:16.834Z"}
|
||||
{"level":"info","message":"Found admin tokens on polygon","timestamp":"2025-04-21T14:42:16.835Z"}
|
||||
{"address":"0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","balance":"499999.9","contract":"0xdce769b847a0a697239777d0b1c7dd33b6012ba0","hasTokens":true,"level":"info","message":"Token balance on arbitrum:","timestamp":"2025-04-21T14:42:17.006Z"}
|
||||
{"level":"info","message":"Found admin tokens on arbitrum","timestamp":"2025-04-21T14:42:17.007Z"}
|
||||
{"balances":{"arbitrum":"499999.9","bsc":"500000.0","eth":"1500000.0","polygon":"454852.0"},"level":"info","message":"Admin role summary for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b:","networks":["bsc","eth","polygon","arbitrum"],"timestamp":"2025-04-21T14:42:17.007Z"}
|
||||
{"level":"info","message":"Admin role granted for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","timestamp":"2025-04-21T14:42:17.007Z"}
|
||||
{"level":"info","message":"Updated user 1 role to admin based on token holdings","timestamp":"2025-04-21T14:42:17.013Z"}
|
||||
{"level":"info","message":"Session saved successfully","timestamp":"2025-04-21T14:42:17.019Z"}
|
||||
{"level":"info","message":"[linkGuestMessages] Starting for user 1 with guestId=undefined, previousGuestId=undefined","timestamp":"2025-04-21T14:42:17.020Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=bdbb9e9a6b156fb309480755554c017c","timestamp":"2025-04-21T14:42:17.023Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=e4ca877a9e8a823241c5f1669ad4b177","timestamp":"2025-04-21T14:42:17.029Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=63404462543ed032df62eb0597cfbf92","timestamp":"2025-04-21T14:42:17.032Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=53e3ea1b2c59ed4f4b37a6402da579db","timestamp":"2025-04-21T14:42:17.036Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=1745240790811-mxagvk0lf","timestamp":"2025-04-21T14:42:17.040Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=8d447b0a532867a90636e000c9bbb72a","timestamp":"2025-04-21T14:42:17.043Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=3987b209726bd85f79f6668c69cec67a","timestamp":"2025-04-21T14:42:17.047Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=e7dd7cc2be1f4cf5628ac67496f0ff60","timestamp":"2025-04-21T14:42:17.050Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=1643e4ae05e31df62ceaa1c784dbf2e7","timestamp":"2025-04-21T14:42:17.054Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=b6de4a34d192b6d3c6a04d64921bc2c6","timestamp":"2025-04-21T14:42:17.057Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=d85d2c40506052a630bb7737bc2769e6","timestamp":"2025-04-21T14:42:17.062Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=8edb112101cbbaa5bef2c3a08f275ec6","timestamp":"2025-04-21T14:42:17.066Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=1745079293895-f5bi3mnlq","timestamp":"2025-04-21T14:42:17.069Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=f74f7950c4b8085f2cead1620d087bb5","timestamp":"2025-04-21T14:42:17.073Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=9c7f2342b8ff1f8fe4d545f6d2af05d4","timestamp":"2025-04-21T14:42:17.076Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=bf299ef8e5ac941443b24bc023d55bdf","timestamp":"2025-04-21T14:42:17.080Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=e70ff3b19f49cb1ce11e3bf9d4c3f5b5","timestamp":"2025-04-21T14:42:17.083Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=dca0cf1d9efe806bc9915e5a57c344b3","timestamp":"2025-04-21T14:42:17.087Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=19ca3c1e1a77f6688e48e996ec94e32b","timestamp":"2025-04-21T14:42:17.090Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=dc34a86ca22b491572bc728db26ec8d2","timestamp":"2025-04-21T14:42:17.094Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=cd399a7b2782ab9dcd510a6d624311ef","timestamp":"2025-04-21T14:42:17.097Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=5fbeaeed77f7e790089e3687b6272cc4","timestamp":"2025-04-21T14:42:17.101Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=06a8da2f6b8ccb05be8606d6f5785c3e","timestamp":"2025-04-21T14:42:17.105Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=12b912bafbdae6136947a2405c43afc7","timestamp":"2025-04-21T14:42:17.109Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=75e90bb5664f78f2d4e89dba9c764340","timestamp":"2025-04-21T14:42:17.112Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=d1a1a0c6759fa0092a9ac54cc6bca38c","timestamp":"2025-04-21T14:42:17.116Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=5c62c06c28391e47ca9da69d82d6b665","timestamp":"2025-04-21T14:42:17.119Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=e1313ff9002847b61b9f8ea825150512","timestamp":"2025-04-21T14:42:17.123Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=4b83b24f9c0cb26179c0637632426e4a","timestamp":"2025-04-21T14:42:17.126Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=221d5a74f84eca5d55db182e0a3d9143","timestamp":"2025-04-21T14:42:17.130Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=7e030d98195da1dd7f81b669c666dca7","timestamp":"2025-04-21T14:42:17.133Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=4256b2a7e0d8b7ed947ba6c1f5f72d15","timestamp":"2025-04-21T14:42:17.136Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=a87f7b05515098ad5a3079377690f769","timestamp":"2025-04-21T14:42:17.141Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=4401b63702956724a4ccb3bb849f7207","timestamp":"2025-04-21T14:42:17.144Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=5957393c426559cd5ffb817d29e4da37","timestamp":"2025-04-21T14:42:17.148Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=064746c1fd4456b7021c936bb9638dfc","timestamp":"2025-04-21T14:42:17.151Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=1745098219233-r5wj2olz0","timestamp":"2025-04-21T14:42:17.155Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=1745243339797-5jz07df5q","timestamp":"2025-04-21T14:42:17.158Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=e50442b5c6fad89fc34176fc078d56f1","timestamp":"2025-04-21T14:42:17.162Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=1745243066352-5zqw1zro4","timestamp":"2025-04-21T14:42:17.165Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=8f897f5f63a679da6893cac2548cdd8c","timestamp":"2025-04-21T14:42:17.169Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=f622d55418e4159e864ea4e6e18115d9","timestamp":"2025-04-21T14:42:17.172Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=cee8775f1ef14ec06069222412527621","timestamp":"2025-04-21T14:42:17.176Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=4801418ef94eac344f7372c5db4bcd41","timestamp":"2025-04-21T14:42:17.180Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=6f93b96d30b4ef36faa2943c5635d949","timestamp":"2025-04-21T14:42:17.184Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=ddf4efa4dca07970401397faae6ad10d","timestamp":"2025-04-21T14:42:17.187Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=a9c5cab9491ffd9a8340488892a3a83f","timestamp":"2025-04-21T14:42:17.190Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=fa541d53f0b7910b5d90be7822f211c0","timestamp":"2025-04-21T14:42:17.194Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=9b1fb20e39a4215abe7c83b8eb752b40","timestamp":"2025-04-21T14:42:17.197Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=750e6a49666b28814122e1d901aea6b5","timestamp":"2025-04-21T14:42:17.201Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=8bbf43a7d107802415e69966ec47edd7","timestamp":"2025-04-21T14:42:17.204Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=784e89fbeba721cf5c3dda2267d9ddd5","timestamp":"2025-04-21T14:42:17.208Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=30c3be3e079722b3a8d20203b1a567f9","timestamp":"2025-04-21T14:42:17.211Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=1745221905698-9rejq7xoe","timestamp":"2025-04-21T14:42:17.215Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=85f386bbe2c9b7affbd50d0366a39147","timestamp":"2025-04-21T14:42:17.218Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=2d284866bfe0da04a3716d3f96d2cc64","timestamp":"2025-04-21T14:42:17.222Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=d6c03e2a1a30f997e7ae94097b8bdc33","timestamp":"2025-04-21T14:42:17.225Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=00e90de9aef9134750d4519a5e10c4ee","timestamp":"2025-04-21T14:42:17.229Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=f79a4edd77d8db2def23394f52e0d0a4","timestamp":"2025-04-21T14:42:17.234Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=b710161e84700cd43778fb846c4017ff","timestamp":"2025-04-21T14:42:17.238Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=5a7dec430e4da72e53b8b07fc1713a4e","timestamp":"2025-04-21T14:42:17.241Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=2f2e2330b4263952294d93ae6a86146a","timestamp":"2025-04-21T14:42:17.245Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=b2e89db3924be1b1d3b0f06f130cf8e0","timestamp":"2025-04-21T14:42:17.250Z"}
|
||||
{"level":"info","message":"[processGuestMessagesWrapper] Processing messages: userId=1, guestId=b4460596d1947e93312e2607cda758ba","timestamp":"2025-04-21T14:42:17.254Z"}
|
||||
{"level":"info","message":"Session saved successfully","timestamp":"2025-04-21T14:42:17.262Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:42:17.275Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:42:17.278Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:42:17.300Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:42:17.306Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:42:17.321Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:42:17.324Z"}
|
||||
{"level":"info","message":"GET /api/tokens/balances","timestamp":"2025-04-21T14:42:17.330Z"}
|
||||
{"level":"info","message":"Fetching token balances for address: 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","timestamp":"2025-04-21T14:42:17.332Z"}
|
||||
{"balance":"1500000.0","contract":"0xd95a45fc46a7300e6022885afec3d618d7d3f27c","level":"info","message":"Token balance for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b on eth:","timestamp":"2025-04-21T14:42:17.758Z"}
|
||||
{"balance":"500000.0","contract":"0x4B294265720B09ca39BFBA18c7E368413c0f68eB","level":"info","message":"Token balance for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b on bsc:","timestamp":"2025-04-21T14:42:18.103Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:42:18.241Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:42:18.244Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:42:18.258Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:42:18.278Z"}
|
||||
{"balance":"499999.9","contract":"0xdce769b847a0a697239777d0b1c7dd33b6012ba0","level":"info","message":"Token balance for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b on arbitrum:","timestamp":"2025-04-21T14:42:18.720Z"}
|
||||
{"balance":"454852.0","contract":"0x351f59de4fedbdf7601f5592b93db3b9330c1c1d","level":"info","message":"Token balance for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b on polygon:","timestamp":"2025-04-21T14:42:19.150Z"}
|
||||
{"arbitrum":"499999.9","bsc":"500000.0","eth":"1500000.0","level":"info","message":"Token balances fetched for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b:","polygon":"454852.0","timestamp":"2025-04-21T14:42:19.150Z"}
|
||||
{"level":"info","message":"GET /api/tokens/balances","timestamp":"2025-04-21T14:42:19.158Z"}
|
||||
{"level":"info","message":"Fetching token balances for address: 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b","timestamp":"2025-04-21T14:42:19.159Z"}
|
||||
{"balance":"1500000.0","contract":"0xd95a45fc46a7300e6022885afec3d618d7d3f27c","level":"info","message":"Token balance for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b on eth:","timestamp":"2025-04-21T14:42:19.602Z"}
|
||||
{"level":"info","message":"POST /api/auth/logout","timestamp":"2025-04-21T14:42:19.890Z"}
|
||||
{"level":"info","message":"Session saved successfully","timestamp":"2025-04-21T14:42:19.893Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:42:19.907Z"}
|
||||
{"level":"info","message":"Session saved successfully","timestamp":"2025-04-21T14:42:19.910Z"}
|
||||
{"balance":"500000.0","contract":"0x4B294265720B09ca39BFBA18c7E368413c0f68eB","level":"info","message":"Token balance for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b on bsc:","timestamp":"2025-04-21T14:42:19.946Z"}
|
||||
{"balance":"499999.9","contract":"0xdce769b847a0a697239777d0b1c7dd33b6012ba0","level":"info","message":"Token balance for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b on arbitrum:","timestamp":"2025-04-21T14:42:20.678Z"}
|
||||
{"balance":"454852.0","contract":"0x351f59de4fedbdf7601f5592b93db3b9330c1c1d","level":"info","message":"Token balance for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b on polygon:","timestamp":"2025-04-21T14:42:21.104Z"}
|
||||
{"arbitrum":"499999.9","bsc":"500000.0","eth":"1500000.0","level":"info","message":"Token balances fetched for 0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b:","polygon":"454852.0","timestamp":"2025-04-21T14:42:21.104Z"}
|
||||
{"level":"info","message":"POST /api/auth/telegram/init","timestamp":"2025-04-21T14:42:21.356Z"}
|
||||
{"level":"info","message":"Generated verification code: FDOU1Z","timestamp":"2025-04-21T14:42:21.357Z"}
|
||||
{"level":"info","message":"Creating verification code for telegram:16236f2b04a47bc549afe4960f6aeded, userId: null","timestamp":"2025-04-21T14:42:21.357Z"}
|
||||
{"level":"info","message":"Verification code created successfully for telegram:16236f2b04a47bc549afe4960f6aeded","timestamp":"2025-04-21T14:42:21.361Z"}
|
||||
{"level":"info","message":"[initTelegramAuth] Created verification code for guestId: 16236f2b04a47bc549afe4960f6aeded","timestamp":"2025-04-21T14:42:21.361Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:42:23.254Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:42:25.753Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:42:27.630Z"}
|
||||
{"level":"info","message":"Starting Telegram auth process for code:","timestamp":"2025-04-21T14:42:29.032Z"}
|
||||
{"level":"info","message":"Using existing user 1 for Telegram account 5155951987","timestamp":"2025-04-21T14:42:29.034Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:42:29.498Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:42:29.499Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:42:29.514Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:42:29.515Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:42:29.527Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:42:29.530Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:42:29.542Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:42:29.586Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:42:31.366Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:42:31.368Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:42:31.382Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=36&limit=30","timestamp":"2025-04-21T14:42:31.396Z"}
|
||||
{"level":"info","message":"POST /api/auth/email/init","timestamp":"2025-04-21T14:42:52.368Z"}
|
||||
{"level":"info","message":"[initEmailAuth] Using existing authenticated user 1 for email hb3accelerator@gmail.com","timestamp":"2025-04-21T14:42:52.372Z"}
|
||||
{"level":"info","message":"Generated verification code: CIC646","timestamp":"2025-04-21T14:42:52.373Z"}
|
||||
{"level":"info","message":"Creating verification code for email:hb3accelerator@gmail.com, userId: 1","timestamp":"2025-04-21T14:42:52.373Z"}
|
||||
{"level":"info","message":"Verification code created successfully for email:hb3accelerator@gmail.com","timestamp":"2025-04-21T14:42:52.377Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error sending verification code: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:42:55.058Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:42:55.058Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:42:55.059Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:43:00.542Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:43:00.544Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:43:29.809Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:43:29.812Z"}
|
||||
{"level":"info","message":"POST /api/auth/email/init","timestamp":"2025-04-21T14:43:48.555Z"}
|
||||
{"level":"info","message":"[initEmailAuth] Using existing authenticated user 1 for email hb3accelerator@gmail.com","timestamp":"2025-04-21T14:43:48.560Z"}
|
||||
{"level":"info","message":"Generated verification code: 1UEQBE","timestamp":"2025-04-21T14:43:48.560Z"}
|
||||
{"level":"info","message":"Creating verification code for email:hb3accelerator@gmail.com, userId: 1","timestamp":"2025-04-21T14:43:48.560Z"}
|
||||
{"level":"info","message":"Verification code created successfully for email:hb3accelerator@gmail.com","timestamp":"2025-04-21T14:43:48.565Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error sending verification code: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:43:53.439Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:43:53.439Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:43:53.440Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:43:59.923Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:43:59.925Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:44:30.983Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:44:30.986Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:45:01.130Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:45:01.133Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:45:39.212Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:45:39.217Z"}
|
||||
{"level":"info","message":"POST /api/auth/email/init","timestamp":"2025-04-21T14:45:40.648Z"}
|
||||
{"level":"info","message":"[initEmailAuth] Using existing authenticated user 1 for email hb3accelerator@gmail.com","timestamp":"2025-04-21T14:45:40.650Z"}
|
||||
{"level":"info","message":"Generated verification code: DPO9NP","timestamp":"2025-04-21T14:45:40.651Z"}
|
||||
{"level":"info","message":"Creating verification code for email:hb3accelerator@gmail.com, userId: 1","timestamp":"2025-04-21T14:45:40.651Z"}
|
||||
{"level":"info","message":"Verification code created successfully for email:hb3accelerator@gmail.com","timestamp":"2025-04-21T14:45:40.654Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error sending verification code: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:45:43.536Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:45:43.537Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:45:43.537Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:46:01.386Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:46:01.389Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:46:29.398Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:46:29.401Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:46:59.562Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:46:59.566Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:47:29.639Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:29.642Z"}
|
||||
{"client":{"_connected":true,"_connecting":false,"_connectionCallback":null,"_connectionError":false,"_connectionTimeoutMillis":0,"_ended":false,"_ending":true,"_events":{},"_eventsCount":1,"_poolUseCount":4,"_queryable":false,"_types":{"_types":{"arrayParser":{},"builtins":{"ABSTIME":702,"ACLITEM":1033,"BIT":1560,"BOOL":16,"BPCHAR":1042,"BYTEA":17,"CHAR":18,"CID":29,"CIDR":650,"CIRCLE":718,"DATE":1082,"FLOAT4":700,"FLOAT8":701,"GTSVECTOR":3642,"INET":869,"INT2":21,"INT4":23,"INT8":20,"INTERVAL":1186,"JSON":114,"JSONB":3802,"MACADDR":829,"MACADDR8":774,"MONEY":790,"NUMERIC":1700,"OID":26,"PATH":602,"PG_DEPENDENCIES":3402,"PG_LSN":3220,"PG_NDISTINCT":3361,"PG_NODE_TREE":194,"POLYGON":604,"REFCURSOR":1790,"REGCLASS":2205,"REGCONFIG":3734,"REGDICTIONARY":3769,"REGNAMESPACE":4089,"REGOPER":2203,"REGOPERATOR":2204,"REGPROC":24,"REGPROCEDURE":2202,"REGROLE":4096,"REGTYPE":2206,"RELTIME":703,"SMGR":210,"TEXT":25,"TID":27,"TIME":1083,"TIMESTAMP":1114,"TIMESTAMPTZ":1184,"TIMETZ":1266,"TINTERVAL":704,"TSQUERY":3615,"TSVECTOR":3614,"TXID_SNAPSHOT":2970,"UUID":2950,"VARBIT":1562,"VARCHAR":1043,"XID":28,"XML":142}},"binary":{},"text":{}},"activeQuery":null,"binary":false,"connection":{"_connecting":true,"_emitMessage":false,"_ending":true,"_events":{"end":[null,null]},"_eventsCount":23,"_keepAlive":false,"_keepAliveInitialDelayMillis":0,"lastBuffer":false,"parsedStatements":{},"ssl":false,"stream":{"_closeAfterHandlingError":false,"_events":{"end":[null,null]},"_eventsCount":4,"_hadError":false,"_host":"postgres","_parent":null,"_pendingData":null,"_pendingEncoding":"","_readableState":{"awaitDrainWriters":null,"buffer":[],"bufferIndex":0,"highWaterMark":16384,"length":0,"pipes":[]},"_server":null,"_sockname":null,"_writableState":{"bufferedIndex":0,"corked":0,"highWaterMark":16384,"length":0,"pendingcb":0,"writelen":0},"allowHalfOpen":false,"connecting":false,"server":null}},"connectionParameters":{"binary":false,"client_encoding":"","connect_timeout":0,"database":"dapp_db","host":"postgres","idle_in_transaction_session_timeout":false,"isDomainSocket":false,"lock_timeout":false,"port":5432,"query_timeout":false,"ssl":false,"statement_timeout":false,"user":"dapp_user"},"database":"dapp_db","hasExecuted":true,"host":"postgres","port":5432,"processID":32813,"queryQueue":[],"readyForQuery":true,"saslSession":null,"secretKey":-471726342,"ssl":false,"user":"dapp_user"},"code":"57P01","file":"postgres.c","length":116,"level":"error","line":"3286","message":"Uncaught Exception: terminating connection due to administrator command","name":"error","routine":"ProcessInterrupts","severity":"FATAL","stack":"error: terminating connection due to administrator command\n at Parser.parseErrorMessage (/app/node_modules/pg-protocol/dist/parser.js:283:98)\n at Parser.handlePacket (/app/node_modules/pg-protocol/dist/parser.js:122:29)\n at Parser.parse (/app/node_modules/pg-protocol/dist/parser.js:35:38)\n at Socket.<anonymous> (/app/node_modules/pg-protocol/dist/index.js:11:42)\n at Socket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)\n at TCP.onStreamRead (node:internal/stream_base_commons:191:23)","timestamp":"2025-04-21T14:47:41.049Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:47:50.599Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:50.616Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:47:50.640Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:50.644Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:47:50.675Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:50.685Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:47:50.701Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:50.706Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:47:50.722Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:50.725Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:47:50.737Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:50.744Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:47:50.752Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:47:50.789Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:47:50.793Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:47:50.818Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:47:51.613Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:51.615Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:47:51.630Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=36&limit=30","timestamp":"2025-04-21T14:47:51.651Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:47:59.736Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:59.738Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:47:59.753Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:59.755Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:47:59.778Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:59.780Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:47:59.793Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:59.795Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:47:59.811Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:59.814Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:47:59.838Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:47:59.841Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:47:59.849Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:47:59.866Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:47:59.878Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:47:59.895Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:48:00.729Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:48:00.731Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:48:00.745Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=36&limit=30","timestamp":"2025-04-21T14:48:00.762Z"}
|
||||
{"level":"info","message":"POST /api/auth/email/init","timestamp":"2025-04-21T14:48:20.774Z"}
|
||||
{"level":"info","message":"[initEmailAuth] Using existing authenticated user 1 for email hb3accelerator@gmail.com","timestamp":"2025-04-21T14:48:20.780Z"}
|
||||
{"level":"info","message":"Generated verification code: TYVZAH","timestamp":"2025-04-21T14:48:20.781Z"}
|
||||
{"level":"info","message":"Creating verification code for email:hb3accelerator@gmail.com, userId: 1","timestamp":"2025-04-21T14:48:20.781Z"}
|
||||
{"level":"info","message":"Verification code created successfully for email:hb3accelerator@gmail.com","timestamp":"2025-04-21T14:48:20.789Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error sending verification code: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:48:23.553Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:48:23.554Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:48:23.554Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:48:29.942Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:48:29.945Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:48:29.956Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:48:29.958Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:49:00.057Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:49:00.060Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:49:00.071Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:49:00.073Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:49:30.195Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:49:30.198Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:49:30.207Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:49:30.209Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:49:47.048Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:49:47.052Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:49:47.074Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:49:47.076Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:49:47.092Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:49:47.094Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:49:47.118Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:49:47.142Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:49:47.169Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=36&limit=30","timestamp":"2025-04-21T14:49:47.187Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:49:48.257Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:49:48.260Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:49:48.278Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=36&limit=30","timestamp":"2025-04-21T14:49:48.299Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:50:00.443Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:50:00.446Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:50:15.384Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:50:15.387Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:50:30.536Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:50:30.539Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:50:45.460Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:50:45.463Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:51:14.633Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:51:14.637Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:51:15.540Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:51:15.541Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:51:45.712Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:51:45.715Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:52:13.860Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:13.864Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:52:21.090Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:21.092Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:52:26.148Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:26.150Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:52:26.170Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:26.172Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:52:26.195Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:26.197Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:52:26.218Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:26.221Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:52:26.238Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:26.240Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:52:26.258Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:26.260Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:52:26.288Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:52:26.307Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:52:26.315Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:52:26.333Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:52:27.158Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:27.160Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:52:27.173Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=36&limit=30","timestamp":"2025-04-21T14:52:27.192Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:52:41.975Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:41.979Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:52:42.003Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:42.005Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:52:42.034Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:42.036Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:52:42.054Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:42.056Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:52:42.073Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:42.076Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:52:42.091Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:42.094Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:52:42.131Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:52:42.156Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:52:42.164Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:52:42.189Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:52:42.977Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:52:42.978Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:52:42.994Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=36&limit=30","timestamp":"2025-04-21T14:52:43.016Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:53:11.492Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:53:11.496Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:53:12.411Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:53:12.413Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:53:41.670Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:53:41.673Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:53:42.585Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:53:42.587Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:54:11.793Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:54:11.795Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:54:12.712Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:54:12.714Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:54:42.849Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:54:42.852Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:54:42.863Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:54:42.870Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:55:12.054Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:55:12.057Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:55:15.772Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:55:15.774Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:56:16.054Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:56:16.058Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:56:16.070Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:56:16.073Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:57:16.339Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:57:16.342Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:57:16.354Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:57:16.356Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:58:00.474Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:58:00.479Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:58:00.489Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:58:00.492Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:58:11.657Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:58:11.659Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:58:11.669Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:58:11.671Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:58:28.544Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:58:28.564Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:58:28.585Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:58:28.590Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:58:28.622Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:58:28.628Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:58:28.652Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:58:28.655Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:58:28.670Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:58:28.672Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:58:28.685Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:58:28.692Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:58:28.700Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:58:28.728Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:58:28.732Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:58:28.753Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:58:29.559Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:58:29.561Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:58:29.575Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=36&limit=30","timestamp":"2025-04-21T14:58:29.594Z"}
|
||||
{"level":"info","message":"POST /api/auth/email/init","timestamp":"2025-04-21T14:58:45.743Z"}
|
||||
{"level":"info","message":"[initEmailAuth] Using existing authenticated user 1 for email hb3accelerator@gmail.com","timestamp":"2025-04-21T14:58:45.748Z"}
|
||||
{"level":"info","message":"Generated verification code: 2G8B80","timestamp":"2025-04-21T14:58:45.749Z"}
|
||||
{"level":"info","message":"Creating verification code for email:hb3accelerator@gmail.com, userId: 1","timestamp":"2025-04-21T14:58:45.749Z"}
|
||||
{"level":"info","message":"Verification code created successfully for email:hb3accelerator@gmail.com","timestamp":"2025-04-21T14:58:45.754Z"}
|
||||
{"level":"info","message":"Verification code sent to hb3accelerator@gmail.com","timestamp":"2025-04-21T14:58:46.694Z"}
|
||||
{"level":"info","message":"Generated verification code for Email auth for hb3accelerator@gmail.com and sent to user's email","timestamp":"2025-04-21T14:58:46.695Z"}
|
||||
{"level":"info","message":"Session saved successfully","timestamp":"2025-04-21T14:58:46.699Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:58:58.901Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:58:58.905Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:58:58.916Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 2 identities for user 1","timestamp":"2025-04-21T14:58:58.918Z"}
|
||||
{"level":"info","message":"POST /api/auth/email/verify-code","timestamp":"2025-04-21T14:59:07.050Z"}
|
||||
{"level":"info","message":"Verifying code for email:hb3accelerator@gmail.com","timestamp":"2025-04-21T14:59:07.051Z"}
|
||||
{"level":"info","message":"Normalized code: 2G8B80","timestamp":"2025-04-21T14:59:07.051Z"}
|
||||
{"level":"info","message":"Found codes for email:hb3accelerator@gmail.com: [\"DPO9NP\",\"TYVZAH\",\"2G8B80\"]","timestamp":"2025-04-21T14:59:07.056Z"}
|
||||
{"level":"info","message":"Code verified successfully for email:hb3accelerator@gmail.com","timestamp":"2025-04-21T14:59:07.060Z"}
|
||||
{"level":"info","message":"[email/verify-code] Linking email hb3accelerator@gmail.com to existing authenticated user 1","timestamp":"2025-04-21T14:59:07.060Z"}
|
||||
{"level":"info","message":"[AuthService] Linking identity email:hb3accelerator@gmail.com to user 1","timestamp":"2025-04-21T14:59:07.061Z"}
|
||||
{"level":"info","message":"[AuthService] Identity email:hb3accelerator@gmail.com successfully linked to user 1","timestamp":"2025-04-21T14:59:07.072Z"}
|
||||
{"level":"info","message":"Session saved successfully","timestamp":"2025-04-21T14:59:07.074Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:59:07.087Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T14:59:07.089Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:59:07.104Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T14:59:07.106Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:59:07.121Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T14:59:07.123Z"}
|
||||
{"level":"info","message":"POST /api/auth/identities/link","timestamp":"2025-04-21T14:59:07.139Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:59:28.925Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T14:59:28.928Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:59:28.940Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T14:59:28.945Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:59:31.705Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T14:59:31.707Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:59:31.720Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T14:59:31.722Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:59:31.742Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T14:59:31.745Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:59:31.761Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T14:59:31.767Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:59:31.782Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T14:59:31.785Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T14:59:31.798Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T14:59:31.801Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:59:31.829Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:59:31.854Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:59:31.861Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T14:59:31.892Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T14:59:32.694Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T14:59:32.696Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T14:59:32.709Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=36&limit=30","timestamp":"2025-04-21T14:59:32.728Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:00:01.973Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:00:01.976Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:00:01.986Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:00:01.988Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:00:32.108Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:00:32.111Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:00:32.126Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:00:32.128Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T15:00:48.645Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:00:48.648Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:00:48.668Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:00:48.671Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:00:48.685Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:00:48.687Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T15:00:48.702Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=36&limit=30","timestamp":"2025-04-21T15:00:48.727Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T15:00:49.852Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:00:49.853Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T15:00:49.867Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T15:00:49.883Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:01:02.246Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:02.249Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T15:01:09.844Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:09.846Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T15:01:09.865Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:09.868Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:01:09.899Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:09.905Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:01:09.926Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:09.930Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:01:09.945Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:09.950Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:01:09.964Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:09.967Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T15:01:10.844Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:10.846Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T15:01:10.861Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T15:01:10.879Z"}
|
||||
{"level":"info","message":"POST /api/auth/logout","timestamp":"2025-04-21T15:01:14.966Z"}
|
||||
{"level":"info","message":"Session saved successfully","timestamp":"2025-04-21T15:01:14.970Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T15:01:14.988Z"}
|
||||
{"level":"info","message":"Session saved successfully","timestamp":"2025-04-21T15:01:14.991Z"}
|
||||
{"level":"info","message":"POST /api/auth/telegram/init","timestamp":"2025-04-21T15:01:17.266Z"}
|
||||
{"level":"info","message":"Generated verification code: 077C49","timestamp":"2025-04-21T15:01:17.267Z"}
|
||||
{"level":"info","message":"Creating verification code for telegram:8890d8475daa4b9515427d7db88cd3f6, userId: null","timestamp":"2025-04-21T15:01:17.267Z"}
|
||||
{"level":"info","message":"Verification code created successfully for telegram:8890d8475daa4b9515427d7db88cd3f6","timestamp":"2025-04-21T15:01:17.270Z"}
|
||||
{"level":"info","message":"[initTelegramAuth] Created verification code for guestId: 8890d8475daa4b9515427d7db88cd3f6","timestamp":"2025-04-21T15:01:17.271Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T15:01:19.151Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T15:01:21.860Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T15:01:23.730Z"}
|
||||
{"level":"info","message":"Starting Telegram auth process for code:","timestamp":"2025-04-21T15:01:25.195Z"}
|
||||
{"level":"info","message":"Using existing user 1 for Telegram account 5155951987","timestamp":"2025-04-21T15:01:25.196Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T15:01:25.611Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:25.613Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:01:25.630Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:25.632Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:01:25.646Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:25.648Z"}
|
||||
{"level":"info","message":"GET /api/auth/check","timestamp":"2025-04-21T15:01:27.473Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:27.474Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?count_only=true","timestamp":"2025-04-21T15:01:27.487Z"}
|
||||
{"level":"info","message":"GET /api/chat/history?offset=6&limit=30","timestamp":"2025-04-21T15:01:27.585Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:01:40.114Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:40.116Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:01:56.741Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:01:56.744Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:02:10.937Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:02:10.941Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:02:26.784Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:02:26.787Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:02:41.062Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:02:41.065Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:02:56.976Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:02:56.979Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:03:11.193Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:03:11.196Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:03:27.119Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:03:27.122Z"}
|
||||
{"level":"info","message":"GET /api/auth/identities","timestamp":"2025-04-21T15:03:41.328Z"}
|
||||
{"level":"info","message":"[IdentityService] Found 3 identities for user 1","timestamp":"2025-04-21T15:03:41.331Z"}
|
||||
|
||||
@@ -37,3 +37,16 @@
|
||||
{"level":"error","message":"Provider for polygon is not available: Network check timeout","timestamp":"2025-04-21T12:36:03.317Z"}
|
||||
{"level":"error","message":"Provider for bsc is not available: Network check timeout","timestamp":"2025-04-21T13:48:41.033Z"}
|
||||
{"level":"error","message":"Provider for polygon is not available: Network check timeout","timestamp":"2025-04-21T13:48:48.026Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error sending verification code: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:42:55.058Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:42:55.058Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:42:55.059Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error sending verification code: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:43:53.439Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:43:53.439Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:43:53.440Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error sending verification code: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:45:43.536Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:45:43.537Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:45:43.537Z"}
|
||||
{"client":{"_connected":true,"_connecting":false,"_connectionCallback":null,"_connectionError":false,"_connectionTimeoutMillis":0,"_ended":false,"_ending":true,"_events":{},"_eventsCount":1,"_poolUseCount":4,"_queryable":false,"_types":{"_types":{"arrayParser":{},"builtins":{"ABSTIME":702,"ACLITEM":1033,"BIT":1560,"BOOL":16,"BPCHAR":1042,"BYTEA":17,"CHAR":18,"CID":29,"CIDR":650,"CIRCLE":718,"DATE":1082,"FLOAT4":700,"FLOAT8":701,"GTSVECTOR":3642,"INET":869,"INT2":21,"INT4":23,"INT8":20,"INTERVAL":1186,"JSON":114,"JSONB":3802,"MACADDR":829,"MACADDR8":774,"MONEY":790,"NUMERIC":1700,"OID":26,"PATH":602,"PG_DEPENDENCIES":3402,"PG_LSN":3220,"PG_NDISTINCT":3361,"PG_NODE_TREE":194,"POLYGON":604,"REFCURSOR":1790,"REGCLASS":2205,"REGCONFIG":3734,"REGDICTIONARY":3769,"REGNAMESPACE":4089,"REGOPER":2203,"REGOPERATOR":2204,"REGPROC":24,"REGPROCEDURE":2202,"REGROLE":4096,"REGTYPE":2206,"RELTIME":703,"SMGR":210,"TEXT":25,"TID":27,"TIME":1083,"TIMESTAMP":1114,"TIMESTAMPTZ":1184,"TIMETZ":1266,"TINTERVAL":704,"TSQUERY":3615,"TSVECTOR":3614,"TXID_SNAPSHOT":2970,"UUID":2950,"VARBIT":1562,"VARCHAR":1043,"XID":28,"XML":142}},"binary":{},"text":{}},"activeQuery":null,"binary":false,"connection":{"_connecting":true,"_emitMessage":false,"_ending":true,"_events":{"end":[null,null]},"_eventsCount":23,"_keepAlive":false,"_keepAliveInitialDelayMillis":0,"lastBuffer":false,"parsedStatements":{},"ssl":false,"stream":{"_closeAfterHandlingError":false,"_events":{"end":[null,null]},"_eventsCount":4,"_hadError":false,"_host":"postgres","_parent":null,"_pendingData":null,"_pendingEncoding":"","_readableState":{"awaitDrainWriters":null,"buffer":[],"bufferIndex":0,"highWaterMark":16384,"length":0,"pipes":[]},"_server":null,"_sockname":null,"_writableState":{"bufferedIndex":0,"corked":0,"highWaterMark":16384,"length":0,"pendingcb":0,"writelen":0},"allowHalfOpen":false,"connecting":false,"server":null}},"connectionParameters":{"binary":false,"client_encoding":"","connect_timeout":0,"database":"dapp_db","host":"postgres","idle_in_transaction_session_timeout":false,"isDomainSocket":false,"lock_timeout":false,"port":5432,"query_timeout":false,"ssl":false,"statement_timeout":false,"user":"dapp_user"},"database":"dapp_db","hasExecuted":true,"host":"postgres","port":5432,"processID":32813,"queryQueue":[],"readyForQuery":true,"saslSession":null,"secretKey":-471726342,"ssl":false,"user":"dapp_user"},"code":"57P01","file":"postgres.c","length":116,"level":"error","line":"3286","message":"Uncaught Exception: terminating connection due to administrator command","name":"error","routine":"ProcessInterrupts","severity":"FATAL","stack":"error: terminating connection due to administrator command\n at Parser.parseErrorMessage (/app/node_modules/pg-protocol/dist/parser.js:283:98)\n at Parser.handlePacket (/app/node_modules/pg-protocol/dist/parser.js:122:29)\n at Parser.parse (/app/node_modules/pg-protocol/dist/parser.js:35:38)\n at Socket.<anonymous> (/app/node_modules/pg-protocol/dist/index.js:11:42)\n at Socket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)\n at TCP.onStreamRead (node:internal/stream_base_commons:191:23)","timestamp":"2025-04-21T14:47:41.049Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error sending verification code: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:48:23.553Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:48:23.554Z"}
|
||||
{"code":"EAUTH","command":"AUTH PLAIN","level":"error","message":"Error in email auth initialization: Invalid login: 535 5.7.8 Error: authentication failed: ","response":"535 5.7.8 Error: authentication failed: ","responseCode":535,"stack":"Error: Invalid login: 535 5.7.8 Error: authentication failed: \n at SMTPConnection._formatError (/app/node_modules/nodemailer/lib/smtp-connection/index.js:809:19)\n at SMTPConnection._actionAUTHComplete (/app/node_modules/nodemailer/lib/smtp-connection/index.js:1588:34)\n at SMTPConnection.<anonymous> (/app/node_modules/nodemailer/lib/smtp-connection/index.js:556:26)\n at SMTPConnection._processResponse (/app/node_modules/nodemailer/lib/smtp-connection/index.js:993:20)\n at SMTPConnection._onData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:774:14)\n at SMTPConnection._onSocketData (/app/node_modules/nodemailer/lib/smtp-connection/index.js:195:44)\n at TLSSocket.emit (node:events:524:28)\n at addChunk (node:internal/streams/readable:561:12)\n at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n at Readable.push (node:internal/streams/readable:392:5)","timestamp":"2025-04-21T14:48:23.554Z"}
|
||||
|
||||
@@ -13,7 +13,7 @@ const requireAuth = async (req, res, next) => {
|
||||
console.log('Session in requireAuth:', {
|
||||
id: req.sessionID,
|
||||
userId: req.session?.userId,
|
||||
authenticated: req.session?.authenticated
|
||||
authenticated: req.session?.authenticated,
|
||||
});
|
||||
|
||||
// Проверяем сессию
|
||||
@@ -25,7 +25,7 @@ const requireAuth = async (req, res, next) => {
|
||||
userId: req.session.userId,
|
||||
address: req.session.address,
|
||||
isAdmin: req.session.isAdmin,
|
||||
authType: req.session.authType
|
||||
authType: req.session.authType,
|
||||
};
|
||||
return next();
|
||||
}
|
||||
@@ -36,13 +36,16 @@ const requireAuth = async (req, res, next) => {
|
||||
const address = authHeader.split(' ')[1];
|
||||
|
||||
if (address.startsWith('0x')) {
|
||||
const result = await db.query(`
|
||||
const result = await db.query(
|
||||
`
|
||||
SELECT u.id, u.is_admin
|
||||
FROM users u
|
||||
JOIN user_identities ui ON u.id = ui.user_id
|
||||
WHERE ui.identity_type = 'wallet'
|
||||
AND LOWER(ui.identity_value) = LOWER($1)
|
||||
`, [address]);
|
||||
`,
|
||||
[address]
|
||||
);
|
||||
|
||||
if (result.rows.length > 0) {
|
||||
const user = result.rows[0];
|
||||
@@ -68,7 +71,7 @@ const requireAuth = async (req, res, next) => {
|
||||
userId: user.id,
|
||||
address: address,
|
||||
isAdmin: user.is_admin,
|
||||
authType: 'wallet'
|
||||
authType: 'wallet',
|
||||
};
|
||||
next();
|
||||
});
|
||||
@@ -111,7 +114,9 @@ async function requireAdmin(req, res, next) {
|
||||
|
||||
// Проверка через ID пользователя
|
||||
if (req.session.userId) {
|
||||
const userResult = await db.query('SELECT role FROM users WHERE id = $1', [req.session.userId]);
|
||||
const userResult = await db.query('SELECT role FROM users WHERE id = $1', [
|
||||
req.session.userId,
|
||||
]);
|
||||
if (userResult.rows.length > 0 && userResult.rows[0].role === USER_ROLES.ADMIN) {
|
||||
// Обновляем сессию
|
||||
req.session.isAdmin = true;
|
||||
@@ -146,7 +151,9 @@ function requireRole(role) {
|
||||
|
||||
// Проверка через ID пользователя
|
||||
if (req.session.userId) {
|
||||
const userResult = await db.query('SELECT role FROM users WHERE id = $1', [req.session.userId]);
|
||||
const userResult = await db.query('SELECT role FROM users WHERE id = $1', [
|
||||
req.session.userId,
|
||||
]);
|
||||
if (userResult.rows.length > 0 && userResult.rows[0].role === role) {
|
||||
return next();
|
||||
}
|
||||
@@ -192,5 +199,5 @@ module.exports = {
|
||||
requireAuth,
|
||||
requireAdmin,
|
||||
requireRole,
|
||||
checkRole
|
||||
checkRole,
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ function errorHandler(err, req, res, next) {
|
||||
url: req.originalUrl,
|
||||
method: req.method,
|
||||
ip: req.ip,
|
||||
userId: req.session?.userId
|
||||
userId: req.session?.userId,
|
||||
});
|
||||
|
||||
// Определяем тип ошибки
|
||||
@@ -39,17 +39,15 @@ function errorHandler(err, req, res, next) {
|
||||
}
|
||||
|
||||
// В режиме разработки возвращаем стек ошибки
|
||||
const devError = process.env.NODE_ENV === 'development'
|
||||
? { stack: err.stack }
|
||||
: {};
|
||||
const devError = process.env.NODE_ENV === 'development' ? { stack: err.stack } : {};
|
||||
|
||||
// Отправляем ответ клиенту
|
||||
res.status(statusCode).json({
|
||||
error: {
|
||||
code: errorCode,
|
||||
message: errorMessage,
|
||||
...devError
|
||||
}
|
||||
...devError,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -67,5 +65,5 @@ function createError(message, status) {
|
||||
|
||||
module.exports = {
|
||||
errorHandler,
|
||||
createError
|
||||
createError,
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const db = require('../db');
|
||||
const { requireAdmin } = require('../middleware/auth');
|
||||
const authService = require('../services/auth-service');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
@@ -37,21 +37,20 @@ router.get('/nonce', async (req, res) => {
|
||||
const nonce = crypto.randomBytes(16).toString('hex');
|
||||
|
||||
// Проверяем, существует ли уже nonce для этого адреса
|
||||
const existingNonce = await db.query(
|
||||
'SELECT id FROM nonces WHERE identity_value = $1',
|
||||
[address.toLowerCase()]
|
||||
);
|
||||
const existingNonce = await db.query('SELECT id FROM nonces WHERE identity_value = $1', [
|
||||
address.toLowerCase(),
|
||||
]);
|
||||
|
||||
if (existingNonce.rows.length > 0) {
|
||||
// Обновляем существующий nonce
|
||||
await db.query(
|
||||
'UPDATE nonces SET nonce = $1, expires_at = NOW() + INTERVAL \'15 minutes\' WHERE identity_value = $2',
|
||||
"UPDATE nonces SET nonce = $1, expires_at = NOW() + INTERVAL '15 minutes' WHERE identity_value = $2",
|
||||
[nonce, address.toLowerCase()]
|
||||
);
|
||||
} else {
|
||||
// Создаем новый nonce
|
||||
await db.query(
|
||||
'INSERT INTO nonces (identity_value, nonce, expires_at) VALUES ($1, $2, NOW() + INTERVAL \'15 minutes\')',
|
||||
"INSERT INTO nonces (identity_value, nonce, expires_at) VALUES ($1, $2, NOW() + INTERVAL '15 minutes')",
|
||||
[address.toLowerCase(), nonce]
|
||||
);
|
||||
}
|
||||
@@ -86,8 +85,13 @@ router.post('/verify', async (req, res) => {
|
||||
const normalizedAddress = ethers.getAddress(address).toLowerCase();
|
||||
|
||||
// Проверяем nonce
|
||||
const nonceResult = await db.query('SELECT nonce FROM nonces WHERE identity_value = $1', [normalizedAddress]);
|
||||
if (nonceResult.rows.length === 0 || nonceResult.rows[0].nonce !== message.match(/Nonce: ([^\n]+)/)[1]) {
|
||||
const nonceResult = await db.query('SELECT nonce FROM nonces WHERE identity_value = $1', [
|
||||
normalizedAddress,
|
||||
]);
|
||||
if (
|
||||
nonceResult.rows.length === 0 ||
|
||||
nonceResult.rows[0].nonce !== message.match(/Nonce: ([^\n]+)/)[1]
|
||||
) {
|
||||
return res.status(401).json({ success: false, error: 'Invalid nonce' });
|
||||
}
|
||||
|
||||
@@ -98,24 +102,24 @@ router.post('/verify', async (req, res) => {
|
||||
if (req.session.authenticated && req.session.userId) {
|
||||
// Если пользователь уже авторизован, привязываем кошелек к существующему пользователю
|
||||
userId = req.session.userId;
|
||||
logger.info(`[verify] Using existing authenticated user ${userId} for wallet ${normalizedAddress}`);
|
||||
logger.info(
|
||||
`[verify] Using existing authenticated user ${userId} for wallet ${normalizedAddress}`
|
||||
);
|
||||
|
||||
// Связываем кошелек с пользователем через identity-service для предотвращения дубликатов
|
||||
const linkResult = await authService.linkIdentity(
|
||||
userId,
|
||||
'wallet',
|
||||
address
|
||||
);
|
||||
const linkResult = await authService.linkIdentity(userId, 'wallet', address);
|
||||
|
||||
if (!linkResult.success && linkResult.error) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: linkResult.error
|
||||
error: linkResult.error,
|
||||
});
|
||||
}
|
||||
|
||||
// Если linkResult.message содержит 'already exists', значит кошелек уже привязан
|
||||
logger.info(`[verify] Wallet ${normalizedAddress} linked to user ${userId}: ${linkResult.message || 'success'}`);
|
||||
logger.info(
|
||||
`[verify] Wallet ${normalizedAddress} linked to user ${userId}: ${linkResult.message || 'success'}`
|
||||
);
|
||||
} else {
|
||||
// Находим или создаем пользователя, если не авторизован
|
||||
const result = await authService.findOrCreateUser(address);
|
||||
@@ -163,9 +167,8 @@ router.post('/verify', async (req, res) => {
|
||||
userId,
|
||||
address: normalizedAddress, // Возвращаем нормализованный адрес
|
||||
isAdmin: adminStatus || isAdmin,
|
||||
authenticated: true
|
||||
authenticated: true,
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
logger.error('[verify] Error:', error);
|
||||
res.status(500).json({ success: false, error: 'Server error' });
|
||||
@@ -180,7 +183,7 @@ router.post('/telegram/verify', async (req, res) => {
|
||||
if (!telegramId || !verificationCode) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Missing required fields'
|
||||
error: 'Missing required fields',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -197,7 +200,7 @@ router.post('/telegram/verify', async (req, res) => {
|
||||
if (!verificationResult.success) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: verificationResult.error || 'Verification failed'
|
||||
error: verificationResult.error || 'Verification failed',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -207,7 +210,7 @@ router.post('/telegram/verify', async (req, res) => {
|
||||
logger.error('[telegram/verify] Error regenerating session:', err);
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
error: 'Session error'
|
||||
error: 'Session error',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -236,14 +239,14 @@ router.post('/telegram/verify', async (req, res) => {
|
||||
userId: verificationResult.userId,
|
||||
role: verificationResult.role,
|
||||
telegramId,
|
||||
isNewUser: verificationResult.isNewUser
|
||||
isNewUser: verificationResult.isNewUser,
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('[telegram/verify] Error:', error);
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
error: 'Internal server error'
|
||||
error: 'Internal server error',
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -266,12 +269,12 @@ router.post('/email/request', authLimiter, async (req, res) => {
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Код подтверждения отправлен на email'
|
||||
message: 'Код подтверждения отправлен на email',
|
||||
});
|
||||
} else {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: result.error || 'Ошибка отправки кода'
|
||||
error: result.error || 'Ошибка отправки кода',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -288,7 +291,7 @@ router.post('/email/verify-code', async (req, res) => {
|
||||
if (!code) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Код подтверждения обязателен'
|
||||
error: 'Код подтверждения обязателен',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -300,7 +303,7 @@ router.post('/email/verify-code', async (req, res) => {
|
||||
if (!req.session.pendingEmail) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Email не найден в сессии. Пожалуйста, запросите код подтверждения снова.'
|
||||
error: 'Email не найден в сессии. Пожалуйста, запросите код подтверждения снова.',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -318,7 +321,7 @@ router.post('/email/verify-code', async (req, res) => {
|
||||
if (!verificationResult.success) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: verificationResult.error || 'Неверный код подтверждения'
|
||||
error: verificationResult.error || 'Неверный код подтверждения',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -330,14 +333,12 @@ router.post('/email/verify-code', async (req, res) => {
|
||||
if (req.session.authenticated && req.session.userId) {
|
||||
// Связываем email с существующим пользователем
|
||||
userId = req.session.userId;
|
||||
logger.info(`[email/verify-code] Linking email ${req.session.pendingEmail} to existing authenticated user ${userId}`);
|
||||
logger.info(
|
||||
`[email/verify-code] Linking email ${req.session.pendingEmail} to existing authenticated user ${userId}`
|
||||
);
|
||||
|
||||
// Связываем email с текущим аккаунтом
|
||||
const linkResult = await authService.linkIdentity(
|
||||
userId,
|
||||
'email',
|
||||
req.session.pendingEmail
|
||||
);
|
||||
const linkResult = await authService.linkIdentity(userId, 'email', req.session.pendingEmail);
|
||||
|
||||
// Сохраняем email в сессии
|
||||
req.session.email = req.session.pendingEmail;
|
||||
@@ -353,7 +354,7 @@ router.post('/email/verify-code', async (req, res) => {
|
||||
userId,
|
||||
email: req.session.email,
|
||||
authenticated: true,
|
||||
linked: true
|
||||
linked: true,
|
||||
});
|
||||
} else {
|
||||
// Если пользователь не авторизован, ищем существующего пользователя или создаем нового
|
||||
@@ -367,24 +368,31 @@ router.post('/email/verify-code', async (req, res) => {
|
||||
if (existingUser) {
|
||||
// Используем существующего пользователя
|
||||
userId = existingUser.id;
|
||||
logger.info(`[email/verify-code] Using existing user ${userId} with email ${req.session.pendingEmail}`);
|
||||
logger.info(
|
||||
`[email/verify-code] Using existing user ${userId} with email ${req.session.pendingEmail}`
|
||||
);
|
||||
} else if (req.session.userId) {
|
||||
// Используем текущего пользователя
|
||||
userId = req.session.userId;
|
||||
logger.info(`[email/verify-code] Using current user ${userId} for email ${req.session.pendingEmail}`);
|
||||
logger.info(
|
||||
`[email/verify-code] Using current user ${userId} for email ${req.session.pendingEmail}`
|
||||
);
|
||||
} else if (req.session.tempUserId) {
|
||||
// Используем временного пользователя
|
||||
userId = req.session.tempUserId;
|
||||
logger.info(`[email/verify-code] Using temporary user ${userId} for email ${req.session.pendingEmail}`);
|
||||
logger.info(
|
||||
`[email/verify-code] Using temporary user ${userId} for email ${req.session.pendingEmail}`
|
||||
);
|
||||
} else {
|
||||
// Создаем нового пользователя
|
||||
const newUser = await db.query(
|
||||
'INSERT INTO users (role) VALUES ($1) RETURNING id',
|
||||
['user']
|
||||
);
|
||||
const newUser = await db.query('INSERT INTO users (role) VALUES ($1) RETURNING id', [
|
||||
'user',
|
||||
]);
|
||||
userId = newUser.rows[0].id;
|
||||
isNewAuth = true;
|
||||
logger.info(`[email/verify-code] Created new user ${userId} for email ${req.session.pendingEmail}`);
|
||||
logger.info(
|
||||
`[email/verify-code] Created new user ${userId} for email ${req.session.pendingEmail}`
|
||||
);
|
||||
}
|
||||
|
||||
// Сохраняем email как идентификатор
|
||||
@@ -420,14 +428,14 @@ router.post('/email/verify-code', async (req, res) => {
|
||||
userId,
|
||||
email: req.session.email,
|
||||
authenticated: true,
|
||||
isNewAuth
|
||||
isNewAuth,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('[email/verify-code] Error:', error);
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
error: 'Ошибка сервера'
|
||||
error: 'Ошибка сервера',
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -444,7 +452,7 @@ router.post('/telegram/init', async (req, res) => {
|
||||
res.json({
|
||||
success: true,
|
||||
verificationCode,
|
||||
botLink
|
||||
botLink,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error initializing Telegram auth:', error);
|
||||
@@ -452,13 +460,13 @@ router.post('/telegram/init', async (req, res) => {
|
||||
if (error.message === 'Telegram уже привязан к этому аккаунту') {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to initialize Telegram auth'
|
||||
error: 'Failed to initialize Telegram auth',
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -471,7 +479,7 @@ router.post('/email/init', async (req, res) => {
|
||||
if (!email || !email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Некорректный формат email'
|
||||
error: 'Некорректный формат email',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -483,13 +491,13 @@ router.post('/email/init', async (req, res) => {
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
message: 'Код верификации отправлен на email'
|
||||
message: 'Код верификации отправлен на email',
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error in email auth initialization:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Внутренняя ошибка сервера'
|
||||
error: 'Внутренняя ошибка сервера',
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -509,10 +517,9 @@ router.get('/check', async (req, res) => {
|
||||
identities = await identityService.getUserIdentities(req.session.userId);
|
||||
|
||||
// Проверяем роль пользователя
|
||||
const roleResult = await db.query(
|
||||
'SELECT role FROM users WHERE id = $1',
|
||||
[req.session.userId]
|
||||
);
|
||||
const roleResult = await db.query('SELECT role FROM users WHERE id = $1', [
|
||||
req.session.userId,
|
||||
]);
|
||||
|
||||
if (roleResult.rows.length > 0) {
|
||||
isAdmin = roleResult.rows[0].role === 'admin';
|
||||
@@ -539,7 +546,7 @@ router.get('/check', async (req, res) => {
|
||||
guestId: req.session.guestId || null,
|
||||
authType,
|
||||
identitiesCount: identities.length,
|
||||
isAdmin: isAdmin || false
|
||||
isAdmin: isAdmin || false,
|
||||
};
|
||||
|
||||
// Добавляем специфические поля в зависимости от типа аутентификации
|
||||
@@ -562,7 +569,7 @@ router.get('/check', async (req, res) => {
|
||||
logger.error('[session/check] Error:', error);
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
error: 'Internal server error'
|
||||
error: 'Internal server error',
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -618,7 +625,7 @@ router.get('/check-access', requireAuth, async (req, res) => {
|
||||
success: true,
|
||||
isAdmin,
|
||||
userId,
|
||||
address
|
||||
address,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -626,9 +633,8 @@ router.get('/check-access', requireAuth, async (req, res) => {
|
||||
success: true,
|
||||
isAdmin: false,
|
||||
userId,
|
||||
address: null
|
||||
address: null,
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
logger.error('Error checking access:', error);
|
||||
return res.status(500).json({ error: 'Internal server error' });
|
||||
@@ -689,7 +695,7 @@ router.post('/wallet', async (req, res) => {
|
||||
if (!address || !nonce || !signature) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Missing required fields'
|
||||
error: 'Missing required fields',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -705,7 +711,7 @@ router.post('/wallet', async (req, res) => {
|
||||
if (!validSignature) {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
error: 'Invalid signature'
|
||||
error: 'Invalid signature',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -717,10 +723,7 @@ router.post('/wallet', async (req, res) => {
|
||||
|
||||
// Обновляем роль пользователя в базе данных, если нужно
|
||||
if (isAdmin) {
|
||||
await db.query(
|
||||
'UPDATE users SET role = $1 WHERE id = $2',
|
||||
['admin', userId]
|
||||
);
|
||||
await db.query('UPDATE users SET role = $1 WHERE id = $2', ['admin', userId]);
|
||||
}
|
||||
|
||||
// Сохраняем идентификаторы
|
||||
@@ -753,14 +756,13 @@ router.post('/wallet', async (req, res) => {
|
||||
userId,
|
||||
address,
|
||||
isAdmin,
|
||||
authenticated: true
|
||||
authenticated: true,
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
logger.error('[wallet] Error:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Server error during wallet authentication'
|
||||
error: 'Server error during wallet authentication',
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -775,13 +777,13 @@ router.get('/identities', requireAuth, async (req, res) => {
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
identities
|
||||
identities,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error getting user identities:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Internal server error'
|
||||
error: 'Internal server error',
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -798,13 +800,13 @@ router.get('/check-session', async (req, res) => {
|
||||
res.json({
|
||||
success: true,
|
||||
guestId: req.session.guestId,
|
||||
isAuthenticated: req.session.authenticated || false
|
||||
isAuthenticated: req.session.authenticated || false,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error checking session:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Internal server error'
|
||||
error: 'Internal server error',
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -819,13 +821,13 @@ router.get('/check-tokens/:address', async (req, res) => {
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
balances
|
||||
balances,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error checking token balances:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Internal server error'
|
||||
error: 'Internal server error',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -44,10 +44,9 @@ async function processGuestMessages(userId, guestId) {
|
||||
console.log('No guest messages found');
|
||||
|
||||
// Помечаем как обработанные, даже если сообщений нет
|
||||
await db.query(
|
||||
'UPDATE guest_user_mapping SET processed = true WHERE guest_id = $1',
|
||||
[guestId]
|
||||
);
|
||||
await db.query('UPDATE guest_user_mapping SET processed = true WHERE guest_id = $1', [
|
||||
guestId,
|
||||
]);
|
||||
|
||||
return { success: true, message: 'No guest messages found' };
|
||||
}
|
||||
@@ -57,7 +56,8 @@ async function processGuestMessages(userId, guestId) {
|
||||
|
||||
// Создаем новый диалог для этих сообщений
|
||||
const firstMessage = guestMessages[0];
|
||||
const title = firstMessage.content.length > 30
|
||||
const title =
|
||||
firstMessage.content.length > 30
|
||||
? `${firstMessage.content.substring(0, 30)}...`
|
||||
: firstMessage.content;
|
||||
|
||||
@@ -91,7 +91,7 @@ async function processGuestMessages(userId, guestId) {
|
||||
'user',
|
||||
'web',
|
||||
guestMessage.created_at,
|
||||
userId // Добавляем userId в сообщение для прямой связи
|
||||
userId, // Добавляем userId в сообщение для прямой связи
|
||||
]
|
||||
);
|
||||
|
||||
@@ -119,7 +119,7 @@ async function processGuestMessages(userId, guestId) {
|
||||
'assistant',
|
||||
'web',
|
||||
new Date(),
|
||||
userId // Добавляем userId в сообщение для прямой связи
|
||||
userId, // Добавляем userId в сообщение для прямой связи
|
||||
]
|
||||
);
|
||||
|
||||
@@ -134,13 +134,14 @@ async function processGuestMessages(userId, guestId) {
|
||||
// Удаляем только успешно обработанные гостевые сообщения
|
||||
if (savedMessageIds.length > 0) {
|
||||
await db.query('DELETE FROM guest_messages WHERE id = ANY($1)', [savedMessageIds]);
|
||||
console.log(`Deleted ${savedMessageIds.length} processed guest messages for guest ID ${guestId}`);
|
||||
console.log(
|
||||
`Deleted ${savedMessageIds.length} processed guest messages for guest ID ${guestId}`
|
||||
);
|
||||
|
||||
// Помечаем гостевой ID как обработанный
|
||||
await db.query(
|
||||
'UPDATE guest_user_mapping SET processed = true WHERE guest_id = $1',
|
||||
[guestId]
|
||||
);
|
||||
await db.query('UPDATE guest_user_mapping SET processed = true WHERE guest_id = $1', [
|
||||
guestId,
|
||||
]);
|
||||
} else {
|
||||
console.log('No guest messages were successfully processed, skipping deletion');
|
||||
}
|
||||
@@ -148,7 +149,7 @@ async function processGuestMessages(userId, guestId) {
|
||||
return {
|
||||
success: true,
|
||||
message: `Processed ${savedMessageIds.length} of ${guestMessages.length} guest messages`,
|
||||
conversationId: conversation.id
|
||||
conversationId: conversation.id,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error processing guest messages:', error);
|
||||
@@ -184,7 +185,7 @@ router.post('/guest-message', async (req, res) => {
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
messageId: result.rows[0].id
|
||||
messageId: result.rows[0].id,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error saving guest message:', error);
|
||||
@@ -201,7 +202,12 @@ router.post('/message', requireAuth, async (req, res) => {
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('Processing message:', { message, conversationId, language, userId: req.session.userId });
|
||||
console.log('Processing message:', {
|
||||
message,
|
||||
conversationId,
|
||||
language,
|
||||
userId: req.session.userId,
|
||||
});
|
||||
const userId = req.session.userId;
|
||||
|
||||
let conversation;
|
||||
@@ -263,7 +269,7 @@ router.post('/message', requireAuth, async (req, res) => {
|
||||
success: true,
|
||||
userMessage: userMessageResult.rows[0],
|
||||
aiMessage: aiMessageResult.rows[0],
|
||||
conversation
|
||||
conversation,
|
||||
};
|
||||
|
||||
res.json(response);
|
||||
@@ -296,7 +302,7 @@ router.get('/history', async (req, res) => {
|
||||
userId: req.session.userId,
|
||||
address: req.session.address,
|
||||
authenticated: req.session.authenticated,
|
||||
guestId: req.session.guestId
|
||||
guestId: req.session.guestId,
|
||||
});
|
||||
|
||||
const limit = parseInt(req.query.limit) || 50;
|
||||
@@ -357,9 +363,8 @@ router.get('/history', async (req, res) => {
|
||||
return res.json({
|
||||
success: true,
|
||||
messages: messages,
|
||||
total: total
|
||||
total: total,
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
logger.error('Error getting chat history:', error);
|
||||
return res.status(500).json({ error: 'Internal server error' });
|
||||
|
||||
@@ -39,7 +39,7 @@ router.post('/link', requireAuth, async (req, res) => {
|
||||
if (existingUserId !== userId) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: `This wallet (${value}) is already linked to another account`
|
||||
error: `This wallet (${value}) is already linked to another account`,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ router.post('/link', requireAuth, async (req, res) => {
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Identity linked successfully',
|
||||
isAdmin: req.session.isAdmin
|
||||
isAdmin: req.session.isAdmin,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error linking identity:', error);
|
||||
@@ -69,7 +69,7 @@ router.post('/link', requireAuth, async (req, res) => {
|
||||
if (error.message && error.message.includes('already belongs to another user')) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: `This identity is already linked to another account`
|
||||
error: `This identity is already linked to another account`,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ router.get('/token-balances', requireAuth, async (req, res) => {
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
balances
|
||||
balances,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error getting token balances:', error);
|
||||
|
||||
@@ -11,7 +11,7 @@ router.get('/balances', requireAuth, async (req, res) => {
|
||||
|
||||
if (!address) {
|
||||
return res.status(400).json({
|
||||
error: 'No wallet address in session'
|
||||
error: 'No wallet address in session',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ router.get('/balances', requireAuth, async (req, res) => {
|
||||
} catch (error) {
|
||||
logger.error('Error fetching token balances:', error);
|
||||
res.status(500).json({
|
||||
error: 'Failed to fetch token balances'
|
||||
error: 'Failed to fetch token balances',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -31,10 +31,7 @@ router.post('/update-language', requireAuth, async (req, res) => {
|
||||
}
|
||||
|
||||
// Обновление языка в базе данных
|
||||
await db.query(
|
||||
'UPDATE users SET preferred_language = $1 WHERE id = $2',
|
||||
[language, userId]
|
||||
);
|
||||
await db.query('UPDATE users SET preferred_language = $1 WHERE id = $2', [language, userId]);
|
||||
|
||||
res.json({ success: true });
|
||||
} catch (error) {
|
||||
@@ -59,10 +56,11 @@ router.post('/update-profile', requireAuth, async (req, res) => {
|
||||
}
|
||||
|
||||
// Обновление имени и фамилии в базе данных
|
||||
await db.query(
|
||||
'UPDATE users SET first_name = $1, last_name = $2 WHERE id = $3',
|
||||
[firstName || null, lastName || null, userId]
|
||||
);
|
||||
await db.query('UPDATE users SET first_name = $1, last_name = $2 WHERE id = $3', [
|
||||
firstName || null,
|
||||
lastName || null,
|
||||
userId,
|
||||
]);
|
||||
|
||||
res.json({ success: true });
|
||||
} catch (error) {
|
||||
@@ -107,7 +105,7 @@ router.get('/profile/current', requireAuth, async (req, res) => {
|
||||
status: user.status,
|
||||
createdAt: user.created_at,
|
||||
preferredLanguage: user.preferred_language,
|
||||
identities
|
||||
identities,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error getting user profile:', error);
|
||||
|
||||
@@ -15,7 +15,7 @@ if (!fs.existsSync(logDir)) {
|
||||
|
||||
const logFile = path.join(logDir, 'fix-duplicates.log');
|
||||
const logger = {
|
||||
log: message => {
|
||||
log: (message) => {
|
||||
const timestamp = new Date().toISOString();
|
||||
const logMessage = `[${timestamp}] ${message}\n`;
|
||||
console.log(message);
|
||||
@@ -27,7 +27,7 @@ const logger = {
|
||||
const logMessage = `[${timestamp}] ERROR: ${message}${errorDetail}\n`;
|
||||
console.error(`ERROR: ${message}${errorDetail}`);
|
||||
fs.appendFileSync(logFile, logMessage);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Создаем подключение к базе данных
|
||||
@@ -116,25 +116,31 @@ async function fixDuplicates(duplicates) {
|
||||
|
||||
// Проверяем, что второй идентификатор в нормализованной форме
|
||||
const remainingId = dup.provider_id1 === normalizedAddress ? dup.id1 : dup.id2;
|
||||
const remainingAddress = dup.provider_id1 === normalizedAddress ? dup.provider_id1 : dup.provider_id2;
|
||||
const remainingAddress =
|
||||
dup.provider_id1 === normalizedAddress ? dup.provider_id1 : dup.provider_id2;
|
||||
|
||||
if (remainingAddress !== normalizedAddress) {
|
||||
logger.log(`Обновление идентификатора ID ${remainingId} до нормализованного значения ${normalizedAddress}`);
|
||||
|
||||
await client.query(
|
||||
'UPDATE user_identities SET provider_id = $1 WHERE id = $2',
|
||||
[normalizedAddress, remainingId]
|
||||
logger.log(
|
||||
`Обновление идентификатора ID ${remainingId} до нормализованного значения ${normalizedAddress}`
|
||||
);
|
||||
|
||||
await client.query('UPDATE user_identities SET provider_id = $1 WHERE id = $2', [
|
||||
normalizedAddress,
|
||||
remainingId,
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
// Если идентификаторы принадлежат разным пользователям, нужно решить конфликт
|
||||
// Для определения какой пользователь является основным, можно использовать:
|
||||
// 1. Количество сообщений/активности
|
||||
// 2. Дату создания аккаунта
|
||||
logger.log(`Конфликт: адрес ${dup.provider_id1}/${dup.provider_id2} привязан к разным пользователям: ${dup.user_id1} и ${dup.user_id2}`);
|
||||
logger.log(
|
||||
`Конфликт: адрес ${dup.provider_id1}/${dup.provider_id2} привязан к разным пользователям: ${dup.user_id1} и ${dup.user_id2}`
|
||||
);
|
||||
|
||||
// Определяем, какой пользователь является основным
|
||||
const userInfoResult = await client.query(`
|
||||
const userInfoResult = await client.query(
|
||||
`
|
||||
SELECT
|
||||
id,
|
||||
(SELECT COUNT(*) FROM messages WHERE user_id = users.id) as message_count,
|
||||
@@ -145,7 +151,9 @@ async function fixDuplicates(duplicates) {
|
||||
id IN ($1, $2)
|
||||
ORDER BY
|
||||
message_count DESC, created_at ASC
|
||||
`, [dup.user_id1, dup.user_id2]);
|
||||
`,
|
||||
[dup.user_id1, dup.user_id2]
|
||||
);
|
||||
|
||||
// Если нет пользователей, пропускаем
|
||||
if (userInfoResult.rows.length === 0) {
|
||||
@@ -157,23 +165,31 @@ async function fixDuplicates(duplicates) {
|
||||
const mainUserId = userInfoResult.rows[0].id;
|
||||
const secondaryUserId = mainUserId === dup.user_id1 ? dup.user_id2 : dup.user_id1;
|
||||
|
||||
logger.log(`Объединение пользователей: сохраняем ID ${mainUserId}, удаляем ID ${secondaryUserId}`);
|
||||
logger.log(
|
||||
`Объединение пользователей: сохраняем ID ${mainUserId}, удаляем ID ${secondaryUserId}`
|
||||
);
|
||||
|
||||
// Переносим все идентификаторы от вторичного пользователя к основному
|
||||
await client.query(`
|
||||
await client.query(
|
||||
`
|
||||
INSERT INTO user_identities (user_id, provider, provider_id)
|
||||
SELECT $1, provider, provider_id
|
||||
FROM user_identities
|
||||
WHERE user_id = $2
|
||||
ON CONFLICT DO NOTHING
|
||||
`, [mainUserId, secondaryUserId]);
|
||||
`,
|
||||
[mainUserId, secondaryUserId]
|
||||
);
|
||||
|
||||
// Переносим сообщения
|
||||
await client.query(`
|
||||
await client.query(
|
||||
`
|
||||
UPDATE messages
|
||||
SET user_id = $1
|
||||
WHERE user_id = $2
|
||||
`, [mainUserId, secondaryUserId]);
|
||||
`,
|
||||
[mainUserId, secondaryUserId]
|
||||
);
|
||||
|
||||
// Переносим другие связанные данные...
|
||||
// ...
|
||||
@@ -227,10 +243,10 @@ async function main() {
|
||||
const normalizedAddress = normalizeWalletAddress(wallet.provider_id);
|
||||
|
||||
if (normalizedAddress !== wallet.provider_id) {
|
||||
await client.query(
|
||||
'UPDATE user_identities SET provider_id = $1 WHERE id = $2',
|
||||
[normalizedAddress, wallet.id]
|
||||
);
|
||||
await client.query('UPDATE user_identities SET provider_id = $1 WHERE id = $2', [
|
||||
normalizedAddress,
|
||||
wallet.id,
|
||||
]);
|
||||
updatedCount++;
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -19,7 +19,7 @@ async function runMigrations() {
|
||||
|
||||
// Получаем список выполненных миграций
|
||||
const { rows } = await pool.query('SELECT name FROM migrations');
|
||||
const executedMigrations = new Set(rows.map(row => row.name));
|
||||
const executedMigrations = new Set(rows.map((row) => row.name));
|
||||
|
||||
// Читаем файлы миграций
|
||||
const migrationsDir = path.join(__dirname, '../db/migrations');
|
||||
@@ -27,7 +27,7 @@ async function runMigrations() {
|
||||
|
||||
// Сортируем файлы по номеру
|
||||
const migrationFiles = files
|
||||
.filter(f => f.endsWith('.sql'))
|
||||
.filter((f) => f.endsWith('.sql'))
|
||||
.sort((a, b) => {
|
||||
const numA = parseInt(a.split('_')[0]);
|
||||
const numB = parseInt(b.split('_')[0]);
|
||||
@@ -55,7 +55,12 @@ async function runMigrations() {
|
||||
|
||||
// Выполняем SQL-функции
|
||||
const functionsDir = path.join(migrationsDir, 'functions');
|
||||
if (await fs.stat(functionsDir).then(() => true).catch(() => false)) {
|
||||
if (
|
||||
await fs
|
||||
.stat(functionsDir)
|
||||
.then(() => true)
|
||||
.catch(() => false)
|
||||
) {
|
||||
const functionFiles = await fs.readdir(functionsDir);
|
||||
|
||||
for (const file of functionFiles) {
|
||||
|
||||
@@ -46,7 +46,9 @@ async function initServices() {
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.code === 409) {
|
||||
logger.warn('Another instance of Telegram bot is running. This is normal during development with nodemon');
|
||||
logger.warn(
|
||||
'Another instance of Telegram bot is running. This is normal during development with nodemon'
|
||||
);
|
||||
// Просто логируем ошибку и продолжаем работу
|
||||
// Бот будет запущен при следующем перезапуске
|
||||
} else {
|
||||
@@ -61,10 +63,11 @@ async function initServices() {
|
||||
}
|
||||
|
||||
// Настройка сессий
|
||||
app.use(session({
|
||||
app.use(
|
||||
session({
|
||||
store: new pgSession({
|
||||
pool: pool,
|
||||
tableName: 'session'
|
||||
tableName: 'session',
|
||||
}),
|
||||
secret: process.env.SESSION_SECRET || 'hb3atoken',
|
||||
resave: false,
|
||||
@@ -72,9 +75,10 @@ app.use(session({
|
||||
cookie: {
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
httpOnly: true,
|
||||
maxAge: 30 * 24 * 60 * 60 * 1000 // 30 дней
|
||||
}
|
||||
}));
|
||||
maxAge: 30 * 24 * 60 * 60 * 1000, // 30 дней
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Маршруты API
|
||||
app.use('/api/users', usersRouter);
|
||||
|
||||
@@ -12,7 +12,8 @@ class AIAssistant {
|
||||
|
||||
// Создание экземпляра ChatOllama с нужными параметрами
|
||||
createChat(language = 'ru') {
|
||||
const systemPrompt = language === 'ru'
|
||||
const systemPrompt =
|
||||
language === 'ru'
|
||||
? 'Вы - полезный ассистент. Отвечайте на русском языке.'
|
||||
: 'You are a helpful assistant. Respond in English.';
|
||||
|
||||
@@ -22,7 +23,7 @@ class AIAssistant {
|
||||
system: systemPrompt,
|
||||
temperature: 0.7,
|
||||
maxTokens: 1000,
|
||||
timeout: 30000 // 30 секунд таймаут
|
||||
timeout: 30000, // 30 секунд таймаут
|
||||
});
|
||||
}
|
||||
|
||||
@@ -38,9 +39,7 @@ class AIAssistant {
|
||||
console.log('getResponse called with:', { message, language });
|
||||
|
||||
// Определяем язык, если не указан явно
|
||||
const detectedLanguage = language === 'auto'
|
||||
? this.detectLanguage(message)
|
||||
: language;
|
||||
const detectedLanguage = language === 'auto' ? this.detectLanguage(message) : language;
|
||||
|
||||
console.log('Detected language:', detectedLanguage);
|
||||
|
||||
@@ -67,7 +66,7 @@ class AIAssistant {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error in getResponse:', error);
|
||||
return "Извините, я не смог обработать ваш запрос. Пожалуйста, попробуйте позже.";
|
||||
return 'Извините, я не смог обработать ваш запрос. Пожалуйста, попробуйте позже.';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +75,8 @@ class AIAssistant {
|
||||
try {
|
||||
console.log('Using fallback request method with:', { message, language });
|
||||
|
||||
const systemPrompt = language === 'ru'
|
||||
const systemPrompt =
|
||||
language === 'ru'
|
||||
? 'Вы - полезный ассистент. Отвечайте на русском языке.'
|
||||
: 'You are a helpful assistant. Respond in English.';
|
||||
|
||||
@@ -91,8 +91,8 @@ class AIAssistant {
|
||||
stream: false,
|
||||
options: {
|
||||
temperature: 0.7,
|
||||
num_predict: 1000
|
||||
}
|
||||
num_predict: 1000,
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -6,15 +6,13 @@ const { processMessage } = require('./ai-assistant'); // Используем AI
|
||||
const verificationService = require('./verification-service'); // Используем сервис верификации
|
||||
|
||||
const ADMIN_CONTRACTS = [
|
||||
{ address: "0xd95a45fc46a7300e6022885afec3d618d7d3f27c", network: "eth" },
|
||||
{ address: "0x4B294265720B09ca39BFBA18c7E368413c0f68eB", network: "bsc" },
|
||||
{ address: "0xdce769b847a0a697239777d0b1c7dd33b6012ba0", network: "arbitrum" },
|
||||
{ address: "0x351f59de4fedbdf7601f5592b93db3b9330c1c1d", network: "polygon" }
|
||||
{ address: '0xd95a45fc46a7300e6022885afec3d618d7d3f27c', network: 'eth' },
|
||||
{ address: '0x4B294265720B09ca39BFBA18c7E368413c0f68eB', network: 'bsc' },
|
||||
{ address: '0xdce769b847a0a697239777d0b1c7dd33b6012ba0', network: 'arbitrum' },
|
||||
{ address: '0x351f59de4fedbdf7601f5592b93db3b9330c1c1d', network: 'polygon' },
|
||||
];
|
||||
|
||||
const ERC20_ABI = [
|
||||
"function balanceOf(address owner) view returns (uint256)"
|
||||
];
|
||||
const ERC20_ABI = ['function balanceOf(address owner) view returns (uint256)'];
|
||||
|
||||
class AuthService {
|
||||
constructor() {
|
||||
@@ -22,7 +20,7 @@ class AuthService {
|
||||
eth: new ethers.JsonRpcProvider(process.env.RPC_URL_ETH),
|
||||
polygon: new ethers.JsonRpcProvider(process.env.RPC_URL_POLYGON),
|
||||
bsc: new ethers.JsonRpcProvider(process.env.RPC_URL_BSC),
|
||||
arbitrum: new ethers.JsonRpcProvider(process.env.RPC_URL_ARBITRUM)
|
||||
arbitrum: new ethers.JsonRpcProvider(process.env.RPC_URL_ARBITRUM),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -56,11 +54,14 @@ class AuthService {
|
||||
const normalizedAddress = ethers.getAddress(address).toLowerCase();
|
||||
|
||||
// Ищем пользователя по адресу в таблице user_identities
|
||||
const userResult = await db.query(`
|
||||
const userResult = await db.query(
|
||||
`
|
||||
SELECT u.* FROM users u
|
||||
JOIN user_identities ui ON u.id = ui.user_id
|
||||
WHERE ui.provider = 'wallet' AND ui.provider_id = $1
|
||||
`, [normalizedAddress]);
|
||||
`,
|
||||
[normalizedAddress]
|
||||
);
|
||||
|
||||
if (userResult.rows.length > 0) {
|
||||
const user = userResult.rows[0];
|
||||
@@ -81,15 +82,14 @@ class AuthService {
|
||||
|
||||
return {
|
||||
userId: user.id,
|
||||
isAdmin: user.role === 'admin'
|
||||
isAdmin: user.role === 'admin',
|
||||
};
|
||||
}
|
||||
|
||||
// Если пользователь не найден, создаем нового
|
||||
const newUserResult = await db.query(
|
||||
'INSERT INTO users (role) VALUES ($1) RETURNING id',
|
||||
['user']
|
||||
);
|
||||
const newUserResult = await db.query('INSERT INTO users (role) VALUES ($1) RETURNING id', [
|
||||
'user',
|
||||
]);
|
||||
|
||||
const userId = newUserResult.rows[0].id;
|
||||
|
||||
@@ -106,7 +106,9 @@ class AuthService {
|
||||
// Если у пользователя есть админские токены, обновляем его роль
|
||||
if (isAdmin) {
|
||||
await db.query('UPDATE users SET role = $1 WHERE id = $2', ['admin', userId]);
|
||||
logger.info(`New user ${userId} with wallet ${normalizedAddress} automatically granted admin role`);
|
||||
logger.info(
|
||||
`New user ${userId} with wallet ${normalizedAddress} automatically granted admin role`
|
||||
);
|
||||
}
|
||||
|
||||
return { userId, isAdmin };
|
||||
@@ -151,17 +153,15 @@ class AuthService {
|
||||
|
||||
await Promise.race([networkCheckPromise, timeoutPromise]);
|
||||
} catch (networkError) {
|
||||
logger.error(`Provider for ${contract.network} is not available: ${networkError.message}`);
|
||||
logger.error(
|
||||
`Provider for ${contract.network} is not available: ${networkError.message}`
|
||||
);
|
||||
balances[contract.network] = 'Error: Network unavailable';
|
||||
errorCount++;
|
||||
return null;
|
||||
}
|
||||
|
||||
const tokenContract = new ethers.Contract(
|
||||
contract.address,
|
||||
ERC20_ABI,
|
||||
provider
|
||||
);
|
||||
const tokenContract = new ethers.Contract(contract.address, ERC20_ABI, provider);
|
||||
|
||||
// Создаем промис с таймаутом
|
||||
const balancePromise = tokenContract.balanceOf(address);
|
||||
@@ -178,7 +178,7 @@ class AuthService {
|
||||
address,
|
||||
contract: contract.address,
|
||||
balance: formattedBalance,
|
||||
hasTokens: balance > 0
|
||||
hasTokens: balance > 0,
|
||||
});
|
||||
|
||||
if (parseFloat(formattedBalance) > 0) {
|
||||
@@ -191,7 +191,7 @@ class AuthService {
|
||||
logger.error(`Error checking balance in ${contract.network}:`, {
|
||||
address,
|
||||
contract: contract.address,
|
||||
error: error.message || 'Unknown error'
|
||||
error: error.message || 'Unknown error',
|
||||
});
|
||||
balances[contract.network] = 'Error';
|
||||
errorCount++;
|
||||
@@ -210,8 +210,10 @@ class AuthService {
|
||||
|
||||
if (foundTokens) {
|
||||
logger.info(`Admin role summary for ${address}:`, {
|
||||
networks: Object.keys(balances).filter(net => balances[net] > 0 && balances[net] !== 'Error'),
|
||||
balances
|
||||
networks: Object.keys(balances).filter(
|
||||
(net) => balances[net] > 0 && balances[net] !== 'Error'
|
||||
),
|
||||
balances,
|
||||
});
|
||||
logger.info(`Admin role granted for ${address}`);
|
||||
return true;
|
||||
@@ -233,7 +235,7 @@ class AuthService {
|
||||
eth: '0',
|
||||
bsc: '0',
|
||||
arbitrum: '0',
|
||||
polygon: '0'
|
||||
polygon: '0',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -259,16 +261,14 @@ class AuthService {
|
||||
|
||||
await Promise.race([networkCheckPromise, networkTimeoutPromise]);
|
||||
} catch (networkError) {
|
||||
logger.error(`Provider for ${contract.network} is not available: ${networkError.message}`);
|
||||
logger.error(
|
||||
`Provider for ${contract.network} is not available: ${networkError.message}`
|
||||
);
|
||||
balances[contract.network] = '0';
|
||||
continue;
|
||||
}
|
||||
|
||||
const tokenContract = new ethers.Contract(
|
||||
contract.address,
|
||||
ERC20_ABI,
|
||||
provider
|
||||
);
|
||||
const tokenContract = new ethers.Contract(contract.address, ERC20_ABI, provider);
|
||||
|
||||
// Создаем промис с таймаутом
|
||||
const balancePromise = tokenContract.balanceOf(address);
|
||||
@@ -283,7 +283,7 @@ class AuthService {
|
||||
logger.info(`Token balance for ${address} on ${contract.network}:`, {
|
||||
contract: contract.address,
|
||||
balance: formattedBalance,
|
||||
timestamp: new Date().toISOString()
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
balances[contract.network] = formattedBalance;
|
||||
@@ -292,7 +292,7 @@ class AuthService {
|
||||
address,
|
||||
contract: contract.address,
|
||||
error: error.message || 'Unknown error',
|
||||
timestamp: new Date().toISOString()
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
balances[contract.network] = '0';
|
||||
}
|
||||
@@ -300,7 +300,7 @@ class AuthService {
|
||||
|
||||
logger.info(`Token balances fetched for ${address}:`, {
|
||||
...balances,
|
||||
timestamp: new Date().toISOString()
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
return balances;
|
||||
@@ -329,13 +329,16 @@ class AuthService {
|
||||
`UPDATE session
|
||||
SET sess = $1
|
||||
WHERE sid = $2`,
|
||||
[JSON.stringify({
|
||||
[
|
||||
JSON.stringify({
|
||||
userId,
|
||||
authenticated,
|
||||
authType,
|
||||
address,
|
||||
cookie: session.cookie
|
||||
}), session.id]
|
||||
cookie: session.cookie,
|
||||
}),
|
||||
session.id,
|
||||
]
|
||||
);
|
||||
|
||||
return true;
|
||||
@@ -410,7 +413,9 @@ class AuthService {
|
||||
|
||||
// Если есть кошелек, проверяем админские токены
|
||||
const isAdmin = await this.checkAdminRole(wallet);
|
||||
logger.info(`Role check for user ${userId} with wallet ${wallet}: ${isAdmin ? 'admin' : 'user'}`);
|
||||
logger.info(
|
||||
`Role check for user ${userId} with wallet ${wallet}: ${isAdmin ? 'admin' : 'user'}`
|
||||
);
|
||||
return isAdmin ? 'admin' : 'user';
|
||||
} catch (error) {
|
||||
logger.error('Error checking user role:', error);
|
||||
@@ -432,10 +437,7 @@ class AuthService {
|
||||
const email = result.providerId;
|
||||
|
||||
// Проверяем, существует ли пользователь с таким email
|
||||
const userResult = await db.query(
|
||||
'SELECT * FROM users WHERE id = $1',
|
||||
[userId]
|
||||
);
|
||||
const userResult = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
|
||||
|
||||
if (userResult.rows.length === 0) {
|
||||
return { verified: false };
|
||||
@@ -459,7 +461,7 @@ class AuthService {
|
||||
userId,
|
||||
email,
|
||||
role,
|
||||
wallet: wallet || null
|
||||
wallet: wallet || null,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('Error checking email verification:', error);
|
||||
@@ -481,7 +483,9 @@ class AuthService {
|
||||
if (session && session.authenticated && session.userId) {
|
||||
// Если есть авторизованный пользователь в сессии, связываем Telegram с ним
|
||||
userId = session.userId;
|
||||
logger.info(`[verifyTelegramAuth] Using existing authenticated user ${userId} from session`);
|
||||
logger.info(
|
||||
`[verifyTelegramAuth] Using existing authenticated user ${userId} from session`
|
||||
);
|
||||
|
||||
// Связываем Telegram с текущим пользователем
|
||||
await this.linkIdentity(userId, 'telegram', telegramId);
|
||||
@@ -491,7 +495,7 @@ class AuthService {
|
||||
userId,
|
||||
role: session.isAdmin ? 'admin' : 'user',
|
||||
telegramId,
|
||||
isNewUser: false
|
||||
isNewUser: false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -509,13 +513,14 @@ class AuthService {
|
||||
if (existingUserResult.rows.length > 0) {
|
||||
const existingUser = existingUserResult.rows[0];
|
||||
userId = existingUser.id;
|
||||
logger.info(`[verifyTelegramAuth] Found existing user ${userId} for Telegram ID ${telegramId}`);
|
||||
logger.info(
|
||||
`[verifyTelegramAuth] Found existing user ${userId} for Telegram ID ${telegramId}`
|
||||
);
|
||||
} else {
|
||||
// Создаем нового пользователя для нового telegramId
|
||||
const newUserResult = await db.query(
|
||||
'INSERT INTO users (role) VALUES ($1) RETURNING id',
|
||||
['user']
|
||||
);
|
||||
const newUserResult = await db.query('INSERT INTO users (role) VALUES ($1) RETURNING id', [
|
||||
'user',
|
||||
]);
|
||||
userId = newUserResult.rows[0].id;
|
||||
isNewUser = true;
|
||||
|
||||
@@ -525,7 +530,9 @@ class AuthService {
|
||||
[userId, 'telegram', telegramId]
|
||||
);
|
||||
|
||||
logger.info(`[verifyTelegramAuth] Created new user ${userId} for Telegram ID ${telegramId}`);
|
||||
logger.info(
|
||||
`[verifyTelegramAuth] Created new user ${userId} for Telegram ID ${telegramId}`
|
||||
);
|
||||
}
|
||||
|
||||
// Если есть гостевой ID в сессии, сохраняем его для нового пользователя
|
||||
@@ -542,7 +549,7 @@ class AuthService {
|
||||
userId,
|
||||
role: 'user',
|
||||
telegramId,
|
||||
isNewUser
|
||||
isNewUser,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('[verifyTelegramAuth] Error:', error);
|
||||
@@ -563,7 +570,8 @@ class AuthService {
|
||||
if (isAdmin) {
|
||||
try {
|
||||
// Находим userId по адресу
|
||||
const userResult = await db.query(`
|
||||
const userResult = await db.query(
|
||||
`
|
||||
SELECT u.id FROM users u
|
||||
JOIN user_identities ui ON u.id = ui.user_id
|
||||
WHERE ui.provider = 'wallet' AND ui.provider_id = $1`,
|
||||
@@ -573,10 +581,7 @@ class AuthService {
|
||||
if (userResult.rows.length > 0) {
|
||||
const userId = userResult.rows[0].id;
|
||||
// Обновляем роль пользователя
|
||||
await db.query(
|
||||
'UPDATE users SET role = $1 WHERE id = $2',
|
||||
['admin', userId]
|
||||
);
|
||||
await db.query('UPDATE users SET role = $1 WHERE id = $2', ['admin', userId]);
|
||||
logger.info(`Updated user ${userId} role to admin based on token holdings`);
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -586,7 +591,8 @@ class AuthService {
|
||||
} else {
|
||||
// Если пользователь не является администратором, сбрасываем роль на "user", если она была "admin"
|
||||
try {
|
||||
const userResult = await db.query(`
|
||||
const userResult = await db.query(
|
||||
`
|
||||
SELECT u.id, u.role FROM users u
|
||||
JOIN user_identities ui ON u.id = ui.user_id
|
||||
WHERE ui.provider = 'wallet' AND ui.provider_id = $1`,
|
||||
@@ -595,10 +601,7 @@ class AuthService {
|
||||
|
||||
if (userResult.rows.length > 0 && userResult.rows[0].role === 'admin') {
|
||||
const userId = userResult.rows[0].id;
|
||||
await db.query(
|
||||
'UPDATE users SET role = $1 WHERE id = $2',
|
||||
['user', userId]
|
||||
);
|
||||
await db.query('UPDATE users SET role = $1 WHERE id = $2', ['user', userId]);
|
||||
logger.info(`Reset user ${userId} role from admin to user (no tokens found)`);
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -624,7 +627,7 @@ class AuthService {
|
||||
const identities = await this.getUserIdentities(userId);
|
||||
|
||||
// Фильтруем только гостевые идентификаторы
|
||||
const guestIdentities = identities.filter(id => id.identity_type === 'guest');
|
||||
const guestIdentities = identities.filter((id) => id.identity_type === 'guest');
|
||||
|
||||
// Если гостевых идентификаторов больше 3, удаляем старые
|
||||
if (guestIdentities.length > 3) {
|
||||
@@ -636,10 +639,7 @@ class AuthService {
|
||||
|
||||
// Удаляем старые идентификаторы
|
||||
for (const identity of identitiesToDelete) {
|
||||
await db.query(
|
||||
'DELETE FROM user_identities WHERE id = $1',
|
||||
[identity.id]
|
||||
);
|
||||
await db.query('DELETE FROM user_identities WHERE id = $1', [identity.id]);
|
||||
logger.info(`Deleted old guest identity: ${identity.identity_value}`);
|
||||
}
|
||||
}
|
||||
@@ -676,9 +676,7 @@ class AuthService {
|
||||
try {
|
||||
const balance = await Promise.race([
|
||||
this.getTokenBalance(address, ADMIN_CONTRACTS.ARBITRUM),
|
||||
new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('TIMEOUT')), timeout)
|
||||
)
|
||||
new Promise((_, reject) => setTimeout(() => reject(new Error('TIMEOUT')), timeout)),
|
||||
]);
|
||||
return { balance, hasTokens: balance > 0 };
|
||||
} catch (error) {
|
||||
@@ -697,7 +695,9 @@ class AuthService {
|
||||
async linkIdentity(userId, provider, providerId) {
|
||||
try {
|
||||
if (!userId || !provider || !providerId) {
|
||||
logger.warn(`[AuthService] Missing parameters for linkIdentity: userId=${userId}, provider=${provider}, providerId=${providerId}`);
|
||||
logger.warn(
|
||||
`[AuthService] Missing parameters for linkIdentity: userId=${userId}, provider=${provider}, providerId=${providerId}`
|
||||
);
|
||||
throw new Error('Missing parameters');
|
||||
}
|
||||
|
||||
@@ -715,7 +715,9 @@ class AuthService {
|
||||
normalizedProviderId = providerId.toLowerCase();
|
||||
}
|
||||
|
||||
logger.info(`[AuthService] Linking identity ${provider}:${normalizedProviderId} to user ${userId}`);
|
||||
logger.info(
|
||||
`[AuthService] Linking identity ${provider}:${normalizedProviderId} to user ${userId}`
|
||||
);
|
||||
|
||||
// Проверяем, существует ли уже такой идентификатор
|
||||
const existingResult = await db.query(
|
||||
@@ -728,11 +730,15 @@ class AuthService {
|
||||
|
||||
// Если идентификатор уже принадлежит этому пользователю, ничего не делаем
|
||||
if (existingUserId === userId) {
|
||||
logger.info(`[AuthService] Identity ${provider}:${normalizedProviderId} already exists for user ${userId}`);
|
||||
logger.info(
|
||||
`[AuthService] Identity ${provider}:${normalizedProviderId} already exists for user ${userId}`
|
||||
);
|
||||
return { success: true, message: 'Identity already exists' };
|
||||
} else {
|
||||
// Если идентификатор принадлежит другому пользователю, возвращаем ошибку
|
||||
logger.warn(`[AuthService] Identity ${provider}:${normalizedProviderId} already belongs to user ${existingUserId}, not user ${userId}`);
|
||||
logger.warn(
|
||||
`[AuthService] Identity ${provider}:${normalizedProviderId} already belongs to user ${existingUserId}, not user ${userId}`
|
||||
);
|
||||
throw new Error(`Identity already belongs to another user (${existingUserId})`);
|
||||
}
|
||||
}
|
||||
@@ -751,76 +757,20 @@ class AuthService {
|
||||
|
||||
// Обновляем роль пользователя в базе данных, если нужно
|
||||
if (isAdmin) {
|
||||
await db.query(
|
||||
'UPDATE users SET role = $1 WHERE id = $2',
|
||||
['admin', userId]
|
||||
);
|
||||
await db.query('UPDATE users SET role = $1 WHERE id = $2', ['admin', userId]);
|
||||
logger.info(`[AuthService] Updated user ${userId} role to admin based on token holdings`);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`[AuthService] Identity ${provider}:${normalizedProviderId} successfully linked to user ${userId}`);
|
||||
logger.info(
|
||||
`[AuthService] Identity ${provider}:${normalizedProviderId} successfully linked to user ${userId}`
|
||||
);
|
||||
return { success: true, isAdmin };
|
||||
} catch (error) {
|
||||
logger.error(`[AuthService] Error linking identity ${provider}:${providerId} to user ${userId}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обработка гостевых сообщений после аутентификации
|
||||
* ПРИМЕЧАНИЕ: Эта функция оставлена для обратной совместимости.
|
||||
* Фактически все маршруты теперь используют версию функции из auth.js,
|
||||
* которая корректно обрабатывает сообщения для всех типов аутентификации.
|
||||
* @deprecated Используйте функцию linkGuestMessagesAfterAuth из routes/auth.js
|
||||
*/
|
||||
async linkGuestMessagesAfterAuth(userId, currentGuestId, previousGuestId) {
|
||||
try {
|
||||
logger.info(`[linkGuestMessagesAfterAuth] Starting for user ${userId} with guestId=${currentGuestId}`);
|
||||
|
||||
// Проверяем, есть ли идентификатор для обработки
|
||||
if (!currentGuestId) {
|
||||
logger.debug('[linkGuestMessagesAfterAuth] No guest ID to process');
|
||||
return { success: true, message: 'No guest ID to process' };
|
||||
}
|
||||
|
||||
// Проверяем, не привязаны ли уже эти гостевые сообщения к другому пользователю
|
||||
const existingMessagesCheck = await db.query(
|
||||
`SELECT DISTINCT user_id
|
||||
FROM messages
|
||||
WHERE guest_message_id IN (
|
||||
SELECT id FROM guest_messages WHERE guest_id = $1
|
||||
)`,
|
||||
[currentGuestId]
|
||||
logger.error(
|
||||
`[AuthService] Error linking identity ${provider}:${providerId} to user ${userId}:`,
|
||||
error
|
||||
);
|
||||
|
||||
if (existingMessagesCheck.rows.length > 0) {
|
||||
const existingUserId = existingMessagesCheck.rows[0].user_id;
|
||||
if (existingUserId !== userId) {
|
||||
logger.warn(`[linkGuestMessagesAfterAuth] Guest messages for ${currentGuestId} are already linked to user ${existingUserId}`);
|
||||
return {
|
||||
success: false,
|
||||
error: 'Guest messages are already linked to another user'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Используем ту же функцию processGuestMessages что и в auth.js
|
||||
const result = await processGuestMessages(userId, currentGuestId);
|
||||
logger.info(`[linkGuestMessagesAfterAuth] Guest messages processed: ${JSON.stringify(result)}`);
|
||||
|
||||
// Если есть предыдущий гостевой ID, обработаем и его
|
||||
if (previousGuestId && previousGuestId !== currentGuestId) {
|
||||
const prevResult = await processGuestMessages(userId, previousGuestId);
|
||||
logger.info(`[linkGuestMessagesAfterAuth] Previous guest messages processed: ${JSON.stringify(prevResult)}`);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
result: result
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('[linkGuestMessagesAfterAuth] Error:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,17 +30,18 @@ class EmailAuth {
|
||||
if (session.authenticated && session.userId) {
|
||||
// Если пользователь уже аутентифицирован, используем его ID
|
||||
userId = session.userId;
|
||||
logger.info(`[initEmailAuth] Using existing authenticated user ${userId} for email ${email}`);
|
||||
logger.info(
|
||||
`[initEmailAuth] Using existing authenticated user ${userId} for email ${email}`
|
||||
);
|
||||
} else if (existingEmailUser.rows.length > 0) {
|
||||
// Если найден пользователь с таким email, используем его ID
|
||||
userId = existingEmailUser.rows[0].id;
|
||||
logger.info(`[initEmailAuth] Found existing user ${userId} with email ${email}`);
|
||||
} else {
|
||||
// Создаем временного пользователя, если нужно будет создать нового
|
||||
const userResult = await db.query(
|
||||
'INSERT INTO users (role) VALUES ($1) RETURNING id',
|
||||
['user']
|
||||
);
|
||||
const userResult = await db.query('INSERT INTO users (role) VALUES ($1) RETURNING id', [
|
||||
'user',
|
||||
]);
|
||||
userId = userResult.rows[0].id;
|
||||
session.tempUserId = userId;
|
||||
logger.info(`[initEmailAuth] Created temporary user ${userId} for email ${email}`);
|
||||
@@ -59,7 +60,9 @@ class EmailAuth {
|
||||
// Отправляем код на email
|
||||
await this.emailBot.sendVerificationCode(email, verificationCode);
|
||||
|
||||
logger.info(`Generated verification code for Email auth for ${email} and sent to user's email`);
|
||||
logger.info(
|
||||
`Generated verification code for Email auth for ${email} and sent to user's email`
|
||||
);
|
||||
|
||||
return { success: true, verificationCode };
|
||||
} catch (error) {
|
||||
@@ -103,18 +106,21 @@ class EmailAuth {
|
||||
return {
|
||||
verified: true,
|
||||
userId: finalUserId,
|
||||
email: email
|
||||
email: email,
|
||||
};
|
||||
}
|
||||
|
||||
// Если пользователь не авторизован, ищем всех пользователей с похожими идентификаторами
|
||||
const identities = {
|
||||
email: email,
|
||||
guest: session.guestId
|
||||
guest: session.guestId,
|
||||
};
|
||||
|
||||
const relatedUsers = await authService.identityService.findRelatedUsers(identities);
|
||||
logger.info(`[checkEmailVerification] Found ${relatedUsers.length} related users for identities:`, identities);
|
||||
logger.info(
|
||||
`[checkEmailVerification] Found ${relatedUsers.length} related users for identities:`,
|
||||
identities
|
||||
);
|
||||
|
||||
if (relatedUsers.length > 0) {
|
||||
// Берем первого найденного пользователя как основного
|
||||
@@ -124,13 +130,17 @@ class EmailAuth {
|
||||
// Мигрируем данные от остальных пользователей к основному
|
||||
for (const userId of relatedUsers.slice(1)) {
|
||||
await authService.identityService.migrateUserData(userId, finalUserId);
|
||||
logger.info(`[checkEmailVerification] Migrated data from user ${userId} to ${finalUserId}`);
|
||||
logger.info(
|
||||
`[checkEmailVerification] Migrated data from user ${userId} to ${finalUserId}`
|
||||
);
|
||||
}
|
||||
|
||||
// Если у нас есть временный пользователь, мигрируем его данные тоже
|
||||
if (session.tempUserId && !relatedUsers.includes(session.tempUserId)) {
|
||||
await authService.identityService.migrateUserData(session.tempUserId, finalUserId);
|
||||
logger.info(`[checkEmailVerification] Migrated temporary user ${session.tempUserId} to ${finalUserId}`);
|
||||
logger.info(
|
||||
`[checkEmailVerification] Migrated temporary user ${session.tempUserId} to ${finalUserId}`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Если связанных пользователей нет, используем временного или создаем нового
|
||||
@@ -154,7 +164,9 @@ class EmailAuth {
|
||||
// Если есть гостевой ID, добавляем его тоже
|
||||
if (session.guestId) {
|
||||
await authService.identityService.saveIdentity(finalUserId, 'guest', session.guestId, true);
|
||||
logger.info(`[checkEmailVerification] Added guest identity ${session.guestId} for user ${finalUserId}`);
|
||||
logger.info(
|
||||
`[checkEmailVerification] Added guest identity ${session.guestId} for user ${finalUserId}`
|
||||
);
|
||||
}
|
||||
|
||||
// Очищаем временные данные
|
||||
@@ -166,7 +178,7 @@ class EmailAuth {
|
||||
return {
|
||||
verified: true,
|
||||
userId: finalUserId,
|
||||
email: email
|
||||
email: email,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('Error checking email verification:', error);
|
||||
|
||||
@@ -19,8 +19,8 @@ const transporter = nodemailer.createTransport({
|
||||
maxConnections: 3,
|
||||
maxMessages: 5,
|
||||
tls: {
|
||||
rejectUnauthorized: false
|
||||
}
|
||||
rejectUnauthorized: false,
|
||||
},
|
||||
});
|
||||
|
||||
// Конфигурация для получения писем
|
||||
@@ -34,8 +34,8 @@ const imapConfig = {
|
||||
keepalive: {
|
||||
interval: 10000,
|
||||
idleInterval: 300000,
|
||||
forceNoop: true
|
||||
}
|
||||
forceNoop: true,
|
||||
},
|
||||
};
|
||||
|
||||
class EmailBotService {
|
||||
@@ -91,7 +91,7 @@ class EmailBotService {
|
||||
</div>
|
||||
<p style="font-size: 14px; color: #999;">Код действителен в течение 15 минут.</p>
|
||||
</div>
|
||||
`
|
||||
`,
|
||||
};
|
||||
|
||||
await this.transporter.sendMail(mailOptions);
|
||||
@@ -191,7 +191,7 @@ class EmailBotService {
|
||||
from: process.env.EMAIL_USER,
|
||||
to,
|
||||
subject,
|
||||
text
|
||||
text,
|
||||
};
|
||||
|
||||
await this.transporter.sendMail(mailOptions);
|
||||
|
||||
@@ -27,7 +27,7 @@ class IdentityService {
|
||||
|
||||
return {
|
||||
provider: normalizedProvider,
|
||||
providerId: normalizedProviderId
|
||||
providerId: normalizedProviderId,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -42,10 +42,12 @@ class IdentityService {
|
||||
async saveIdentity(userId, provider, providerId, verified = true) {
|
||||
try {
|
||||
if (!userId || !provider || !providerId) {
|
||||
logger.warn(`[IdentityService] Missing required parameters: userId=${userId}, provider=${provider}, providerId=${providerId}`);
|
||||
logger.warn(
|
||||
`[IdentityService] Missing required parameters: userId=${userId}, provider=${provider}, providerId=${providerId}`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
error: 'Missing required parameters'
|
||||
error: 'Missing required parameters',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -55,7 +57,9 @@ class IdentityService {
|
||||
|
||||
// Проверяем тип провайдера и перенаправляем гостевые идентификаторы в guest_user_mapping
|
||||
if (normalizedProvider === 'guest') {
|
||||
logger.info(`[IdentityService] Converting guest identity for user ${userId} to guest_user_mapping: ${normalizedProviderId}`);
|
||||
logger.info(
|
||||
`[IdentityService] Converting guest identity for user ${userId} to guest_user_mapping: ${normalizedProviderId}`
|
||||
);
|
||||
|
||||
try {
|
||||
await db.query(
|
||||
@@ -64,7 +68,10 @@ class IdentityService {
|
||||
);
|
||||
return { success: true };
|
||||
} catch (guestError) {
|
||||
logger.error(`[IdentityService] Error saving guest identity for user ${userId}:`, guestError);
|
||||
logger.error(
|
||||
`[IdentityService] Error saving guest identity for user ${userId}:`,
|
||||
guestError
|
||||
);
|
||||
return { success: false, error: guestError.message };
|
||||
}
|
||||
}
|
||||
@@ -75,11 +82,13 @@ class IdentityService {
|
||||
logger.warn(`[IdentityService] Invalid provider type: ${normalizedProvider}`);
|
||||
return {
|
||||
success: false,
|
||||
error: `Invalid provider type. Allowed types: ${allowedProviders.join(', ')}`
|
||||
error: `Invalid provider type. Allowed types: ${allowedProviders.join(', ')}`,
|
||||
};
|
||||
}
|
||||
|
||||
logger.info(`[IdentityService] Saving identity for user ${userId}: ${normalizedProvider}:${normalizedProviderId}`);
|
||||
logger.info(
|
||||
`[IdentityService] Saving identity for user ${userId}: ${normalizedProvider}:${normalizedProviderId}`
|
||||
);
|
||||
|
||||
// Проверяем, существует ли уже такой идентификатор
|
||||
const existingResult = await db.query(
|
||||
@@ -92,13 +101,17 @@ class IdentityService {
|
||||
|
||||
// Если идентификатор уже принадлежит этому пользователю, ничего не делаем
|
||||
if (existingUserId === userId) {
|
||||
logger.info(`[IdentityService] Identity ${normalizedProvider}:${normalizedProviderId} already exists for user ${userId}`);
|
||||
logger.info(
|
||||
`[IdentityService] Identity ${normalizedProvider}:${normalizedProviderId} already exists for user ${userId}`
|
||||
);
|
||||
} else {
|
||||
// Если идентификатор принадлежит другому пользователю, логируем это
|
||||
logger.warn(`[IdentityService] Identity ${normalizedProvider}:${normalizedProviderId} already belongs to user ${existingUserId}, not user ${userId}`);
|
||||
logger.warn(
|
||||
`[IdentityService] Identity ${normalizedProvider}:${normalizedProviderId} already belongs to user ${existingUserId}, not user ${userId}`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
error: `Identity already belongs to another user (${existingUserId})`
|
||||
error: `Identity already belongs to another user (${existingUserId})`,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
@@ -108,12 +121,17 @@ class IdentityService {
|
||||
VALUES ($1, $2, $3)`,
|
||||
[userId, normalizedProvider, normalizedProviderId]
|
||||
);
|
||||
logger.info(`[IdentityService] Created new identity ${normalizedProvider}:${normalizedProviderId} for user ${userId}`);
|
||||
logger.info(
|
||||
`[IdentityService] Created new identity ${normalizedProvider}:${normalizedProviderId} for user ${userId}`
|
||||
);
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
logger.error(`[IdentityService] Error saving identity ${provider}:${providerId} for user ${userId}:`, error);
|
||||
logger.error(
|
||||
`[IdentityService] Error saving identity ${provider}:${providerId} for user ${userId}:`,
|
||||
error
|
||||
);
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
}
|
||||
@@ -161,10 +179,15 @@ class IdentityService {
|
||||
[userId, provider]
|
||||
);
|
||||
|
||||
logger.info(`[IdentityService] Found ${result.rows.length} ${provider} identities for user ${userId}`);
|
||||
return result.rows.map(row => row.provider_id);
|
||||
logger.info(
|
||||
`[IdentityService] Found ${result.rows.length} ${provider} identities for user ${userId}`
|
||||
);
|
||||
return result.rows.map((row) => row.provider_id);
|
||||
} catch (error) {
|
||||
logger.error(`[IdentityService] Error getting ${provider} identities for user ${userId}:`, error);
|
||||
logger.error(
|
||||
`[IdentityService] Error getting ${provider} identities for user ${userId}:`,
|
||||
error
|
||||
);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -178,7 +201,9 @@ class IdentityService {
|
||||
async findUserByIdentity(provider, providerId) {
|
||||
try {
|
||||
if (!provider || !providerId) {
|
||||
logger.warn(`[IdentityService] Missing parameters: provider=${provider}, providerId=${providerId}`);
|
||||
logger.warn(
|
||||
`[IdentityService] Missing parameters: provider=${provider}, providerId=${providerId}`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -194,14 +219,21 @@ class IdentityService {
|
||||
);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
logger.info(`[IdentityService] No user found with identity ${normalizedProvider}:${normalizedProviderId}`);
|
||||
logger.info(
|
||||
`[IdentityService] No user found with identity ${normalizedProvider}:${normalizedProviderId}`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
logger.info(`[IdentityService] Found user ${result.rows[0].id} with identity ${normalizedProvider}:${normalizedProviderId}`);
|
||||
logger.info(
|
||||
`[IdentityService] Found user ${result.rows[0].id} with identity ${normalizedProvider}:${normalizedProviderId}`
|
||||
);
|
||||
return result.rows[0];
|
||||
} catch (error) {
|
||||
logger.error(`[IdentityService] Error finding user by identity ${provider}:${providerId}:`, error);
|
||||
logger.error(
|
||||
`[IdentityService] Error finding user by identity ${provider}:${providerId}:`,
|
||||
error
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -233,7 +265,12 @@ class IdentityService {
|
||||
}
|
||||
|
||||
if (session.telegramId) {
|
||||
const telegramResult = await this.saveIdentity(userId, 'telegram', session.telegramId, true);
|
||||
const telegramResult = await this.saveIdentity(
|
||||
userId,
|
||||
'telegram',
|
||||
session.telegramId,
|
||||
true
|
||||
);
|
||||
results.push({ type: 'telegram', result: telegramResult });
|
||||
}
|
||||
|
||||
@@ -259,15 +296,23 @@ class IdentityService {
|
||||
);
|
||||
results.push({ type: 'previousGuest', result: { success: true } });
|
||||
} catch (error) {
|
||||
logger.error(`[IdentityService] Error saving previous guest ID for user ${userId}:`, error);
|
||||
logger.error(
|
||||
`[IdentityService] Error saving previous guest ID for user ${userId}:`,
|
||||
error
|
||||
);
|
||||
results.push({ type: 'previousGuest', result: { success: false, error: error.message } });
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`[IdentityService] Saved ${results.length} identities from session for user ${userId}`);
|
||||
logger.info(
|
||||
`[IdentityService] Saved ${results.length} identities from session for user ${userId}`
|
||||
);
|
||||
return { success: true, results };
|
||||
} catch (error) {
|
||||
logger.error(`[IdentityService] Error saving identities from session for user ${userId}:`, error);
|
||||
logger.error(
|
||||
`[IdentityService] Error saving identities from session for user ${userId}:`,
|
||||
error
|
||||
);
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
}
|
||||
@@ -281,7 +326,9 @@ class IdentityService {
|
||||
async migrateUserData(fromUserId, toUserId) {
|
||||
try {
|
||||
if (!fromUserId || !toUserId) {
|
||||
logger.warn(`[IdentityService] Missing parameters: fromUserId=${fromUserId}, toUserId=${toUserId}`);
|
||||
logger.warn(
|
||||
`[IdentityService] Missing parameters: fromUserId=${fromUserId}, toUserId=${toUserId}`
|
||||
);
|
||||
return { success: false, error: 'Missing required parameters' };
|
||||
}
|
||||
|
||||
@@ -331,10 +378,7 @@ class IdentityService {
|
||||
}
|
||||
|
||||
// Удаляем старые гостевые маппинги
|
||||
await client.query(
|
||||
`DELETE FROM guest_user_mapping WHERE user_id = $1`,
|
||||
[fromUserId]
|
||||
);
|
||||
await client.query(`DELETE FROM guest_user_mapping WHERE user_id = $1`, [fromUserId]);
|
||||
|
||||
// Переносим все сообщения
|
||||
await client.query(
|
||||
@@ -363,7 +407,9 @@ class IdentityService {
|
||||
// Завершаем транзакцию
|
||||
await client.query('COMMIT');
|
||||
|
||||
logger.info(`[IdentityService] Successfully migrated data from user ${fromUserId} to ${toUserId}`);
|
||||
logger.info(
|
||||
`[IdentityService] Successfully migrated data from user ${fromUserId} to ${toUserId}`
|
||||
);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
await client.query('ROLLBACK');
|
||||
@@ -397,7 +443,7 @@ class IdentityService {
|
||||
[provider, providerId]
|
||||
);
|
||||
|
||||
result.rows.forEach(row => userIds.add(row.user_id));
|
||||
result.rows.forEach((row) => userIds.add(row.user_id));
|
||||
}
|
||||
|
||||
return Array.from(userIds);
|
||||
|
||||
@@ -31,5 +31,5 @@ module.exports = {
|
||||
getConversationHistory: aiAssistant.getConversationHistory,
|
||||
|
||||
telegramBot,
|
||||
aiAssistant
|
||||
aiAssistant,
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ class SessionService {
|
||||
async saveSession(session) {
|
||||
try {
|
||||
return new Promise((resolve, reject) => {
|
||||
session.save(err => {
|
||||
session.save((err) => {
|
||||
if (err) {
|
||||
logger.error('Error saving session:', err);
|
||||
reject(err);
|
||||
@@ -38,7 +38,9 @@ class SessionService {
|
||||
*/
|
||||
async linkGuestMessages(session, userId) {
|
||||
try {
|
||||
logger.info(`[linkGuestMessages] Starting for user ${userId} with guestId=${session.guestId}, previousGuestId=${session.previousGuestId}`);
|
||||
logger.info(
|
||||
`[linkGuestMessages] Starting for user ${userId} with guestId=${session.guestId}, previousGuestId=${session.previousGuestId}`
|
||||
);
|
||||
|
||||
// Инициализируем массив обработанных гостевых ID, если его нет
|
||||
if (!session.processedGuestIds) {
|
||||
@@ -50,7 +52,7 @@ class SessionService {
|
||||
'SELECT guest_id FROM guest_user_mapping WHERE user_id = $1',
|
||||
[userId]
|
||||
);
|
||||
const userGuestIds = guestIdsResult.rows.map(row => row.guest_id);
|
||||
const userGuestIds = guestIdsResult.rows.map((row) => row.guest_id);
|
||||
|
||||
// Собираем все гостевые ID, которые нужно обработать
|
||||
const guestIdsToProcess = new Set();
|
||||
@@ -90,10 +92,9 @@ class SessionService {
|
||||
session.processedGuestIds.push(guestId);
|
||||
|
||||
// Помечаем guestId как обработанный в базе данных
|
||||
await db.query(
|
||||
'UPDATE guest_user_mapping SET processed = true WHERE guest_id = $1',
|
||||
[guestId]
|
||||
);
|
||||
await db.query('UPDATE guest_user_mapping SET processed = true WHERE guest_id = $1', [
|
||||
guestId,
|
||||
]);
|
||||
}
|
||||
|
||||
// Сохраняем сессию
|
||||
@@ -114,7 +115,9 @@ class SessionService {
|
||||
*/
|
||||
async processGuestMessagesWrapper(userId, guestId) {
|
||||
try {
|
||||
logger.info(`[processGuestMessagesWrapper] Processing messages: userId=${userId}, guestId=${guestId}`);
|
||||
logger.info(
|
||||
`[processGuestMessagesWrapper] Processing messages: userId=${userId}, guestId=${guestId}`
|
||||
);
|
||||
return await processGuestMessages(userId, guestId);
|
||||
} catch (error) {
|
||||
logger.error(`[processGuestMessagesWrapper] Error: ${error.message}`, error);
|
||||
@@ -146,7 +149,7 @@ class SessionService {
|
||||
async destroySession(session) {
|
||||
try {
|
||||
return new Promise((resolve, reject) => {
|
||||
session.destroy(err => {
|
||||
session.destroy((err) => {
|
||||
if (err) {
|
||||
logger.error('Error destroying session:', err);
|
||||
reject(err);
|
||||
@@ -176,10 +179,7 @@ class SessionService {
|
||||
|
||||
logger.info(`[SessionService] Attempting to retrieve session ${sessionId}`);
|
||||
|
||||
const result = await db.query(
|
||||
'SELECT sess FROM session WHERE sid = $1',
|
||||
[sessionId]
|
||||
);
|
||||
const result = await db.query('SELECT sess FROM session WHERE sid = $1', [sessionId]);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
logger.info(`[SessionService] No session found with ID ${sessionId}`);
|
||||
|
||||
@@ -43,10 +43,9 @@ async function getBot() {
|
||||
let userId;
|
||||
|
||||
// Отмечаем код как использованный
|
||||
await db.query(
|
||||
'UPDATE verification_codes SET used = true WHERE id = $1',
|
||||
[verification.id]
|
||||
);
|
||||
await db.query('UPDATE verification_codes SET used = true WHERE id = $1', [
|
||||
verification.id,
|
||||
]);
|
||||
|
||||
logger.info('Starting Telegram auth process for code:', code);
|
||||
|
||||
@@ -74,7 +73,9 @@ async function getBot() {
|
||||
VALUES ($1, $2, $3, NOW())`,
|
||||
[userId, 'telegram', ctx.from.id.toString()]
|
||||
);
|
||||
logger.info(`Linked Telegram account ${ctx.from.id} to pre-authenticated user ${userId}`);
|
||||
logger.info(
|
||||
`Linked Telegram account ${ctx.from.id} to pre-authenticated user ${userId}`
|
||||
);
|
||||
} else {
|
||||
// Проверяем, есть ли пользователь, связанный с гостевым идентификатором
|
||||
let existingUserWithGuestId = null;
|
||||
@@ -85,7 +86,9 @@ async function getBot() {
|
||||
);
|
||||
if (guestUserResult.rows.length > 0) {
|
||||
existingUserWithGuestId = guestUserResult.rows[0].user_id;
|
||||
logger.info(`Found existing user ${existingUserWithGuestId} by guest ID ${providerId}`);
|
||||
logger.info(
|
||||
`Found existing user ${existingUserWithGuestId} by guest ID ${providerId}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,10 +143,10 @@ async function getBot() {
|
||||
JSON.stringify({
|
||||
userId: userId.toString(),
|
||||
authenticated: true,
|
||||
authType: "telegram",
|
||||
telegramId: ctx.from.id.toString()
|
||||
authType: 'telegram',
|
||||
telegramId: ctx.from.id.toString(),
|
||||
}),
|
||||
JSON.stringify({guestId: providerId})
|
||||
JSON.stringify({ guestId: providerId }),
|
||||
]
|
||||
);
|
||||
|
||||
@@ -156,7 +159,6 @@ async function getBot() {
|
||||
} catch (error) {
|
||||
logger.warn('Could not delete code message:', error);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
logger.error('Error in Telegram auth:', error);
|
||||
await ctx.reply('Произошла ошибка при аутентификации. Попробуйте позже.');
|
||||
@@ -204,7 +206,9 @@ async function initTelegramAuth(session) {
|
||||
[session.userId, guestId]
|
||||
);
|
||||
|
||||
logger.info(`[initTelegramAuth] Linked guestId ${guestId} to authenticated user ${session.userId}`);
|
||||
logger.info(
|
||||
`[initTelegramAuth] Linked guestId ${guestId} to authenticated user ${session.userId}`
|
||||
);
|
||||
}
|
||||
|
||||
// Создаем код через сервис верификации с идентификатором
|
||||
@@ -214,11 +218,13 @@ async function initTelegramAuth(session) {
|
||||
session.authenticated ? session.userId : null
|
||||
);
|
||||
|
||||
logger.info(`[initTelegramAuth] Created verification code for guestId: ${session.guestId || tempId}${session.authenticated ? `, userId: ${session.userId}` : ''}`);
|
||||
logger.info(
|
||||
`[initTelegramAuth] Created verification code for guestId: ${session.guestId || tempId}${session.authenticated ? `, userId: ${session.userId}` : ''}`
|
||||
);
|
||||
|
||||
return {
|
||||
verificationCode: code,
|
||||
botLink: `https://t.me/${process.env.TELEGRAM_BOT_USERNAME}`
|
||||
botLink: `https://t.me/${process.env.TELEGRAM_BOT_USERNAME}`,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('Error initializing Telegram auth:', error);
|
||||
@@ -229,5 +235,5 @@ async function initTelegramAuth(session) {
|
||||
module.exports = {
|
||||
getBot,
|
||||
stopBot,
|
||||
initTelegramAuth
|
||||
initTelegramAuth,
|
||||
};
|
||||
@@ -9,7 +9,10 @@ class VerificationService {
|
||||
|
||||
// Генерация кода
|
||||
generateCode() {
|
||||
const code = Math.random().toString(36).substring(2, 2 + this.codeLength).toUpperCase();
|
||||
const code = Math.random()
|
||||
.toString(36)
|
||||
.substring(2, 2 + this.codeLength)
|
||||
.toUpperCase();
|
||||
logger.info(`Generated verification code: ${code}`);
|
||||
return code;
|
||||
}
|
||||
@@ -20,7 +23,9 @@ class VerificationService {
|
||||
const expiresAt = new Date(Date.now() + this.expirationMinutes * 60 * 1000);
|
||||
|
||||
try {
|
||||
logger.info(`Creating verification code for ${provider}:${providerId}, userId: ${userId || 'null'}`);
|
||||
logger.info(
|
||||
`Creating verification code for ${provider}:${providerId}, userId: ${userId || 'null'}`
|
||||
);
|
||||
|
||||
// Если userId не указан, добавляем запись без ссылки на пользователя
|
||||
if (userId === null || userId === undefined) {
|
||||
@@ -46,7 +51,7 @@ class VerificationService {
|
||||
error: error.message,
|
||||
provider,
|
||||
providerId,
|
||||
userId
|
||||
userId,
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
@@ -72,7 +77,9 @@ class VerificationService {
|
||||
);
|
||||
|
||||
if (checkResult.rows.length > 0) {
|
||||
logger.info(`Found codes for ${provider}:${providerId}: ${JSON.stringify(checkResult.rows.map(r => r.code))}`);
|
||||
logger.info(
|
||||
`Found codes for ${provider}:${providerId}: ${JSON.stringify(checkResult.rows.map((r) => r.code))}`
|
||||
);
|
||||
} else {
|
||||
logger.warn(`No active codes found for ${provider}:${providerId}`);
|
||||
}
|
||||
@@ -88,30 +95,29 @@ class VerificationService {
|
||||
);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
logger.warn(`Invalid or expired code for ${provider}:${providerId}. Input: ${normalizedCode}`);
|
||||
logger.warn(
|
||||
`Invalid or expired code for ${provider}:${providerId}. Input: ${normalizedCode}`
|
||||
);
|
||||
return { success: false, error: 'Неверный или истекший код' };
|
||||
}
|
||||
|
||||
const verification = result.rows[0];
|
||||
|
||||
// Отмечаем код как использованный
|
||||
await db.query(
|
||||
'UPDATE verification_codes SET used = true WHERE id = $1',
|
||||
[verification.id]
|
||||
);
|
||||
await db.query('UPDATE verification_codes SET used = true WHERE id = $1', [verification.id]);
|
||||
|
||||
logger.info(`Code verified successfully for ${provider}:${providerId}`);
|
||||
return {
|
||||
success: true,
|
||||
userId: verification.user_id,
|
||||
providerId: verification.provider_id
|
||||
providerId: verification.provider_id,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('Error verifying code:', {
|
||||
error: error.message,
|
||||
code,
|
||||
provider,
|
||||
providerId
|
||||
providerId,
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
// Роли пользователей
|
||||
const USER_ROLES = {
|
||||
USER: 1,
|
||||
ADMIN: 2
|
||||
ADMIN: 2,
|
||||
};
|
||||
|
||||
// Типы идентификаторов
|
||||
const IDENTITY_TYPES = {
|
||||
WALLET: 'wallet',
|
||||
EMAIL: 'email',
|
||||
TELEGRAM: 'telegram'
|
||||
TELEGRAM: 'telegram',
|
||||
};
|
||||
|
||||
// Каналы сообщений
|
||||
const MESSAGE_CHANNELS = {
|
||||
WEB: 'web',
|
||||
TELEGRAM: 'telegram',
|
||||
EMAIL: 'email'
|
||||
EMAIL: 'email',
|
||||
};
|
||||
|
||||
// Типы отправителей сообщений
|
||||
const SENDER_TYPES = {
|
||||
USER: 'user',
|
||||
AI: 'ai',
|
||||
ADMIN: 'admin'
|
||||
ADMIN: 'admin',
|
||||
};
|
||||
|
||||
// Коды ошибок
|
||||
@@ -31,20 +31,20 @@ const ERROR_CODES = {
|
||||
FORBIDDEN: 'forbidden',
|
||||
NOT_FOUND: 'not_found',
|
||||
INTERNAL_ERROR: 'internal_error',
|
||||
BAD_REQUEST: 'bad_request'
|
||||
BAD_REQUEST: 'bad_request',
|
||||
};
|
||||
|
||||
// Настройки сессии
|
||||
const SESSION_CONFIG = {
|
||||
COOKIE_MAX_AGE: 24 * 60 * 60 * 1000, // 24 часа
|
||||
COOKIE_SECURE: process.env.NODE_ENV === 'production',
|
||||
COOKIE_SAME_SITE: 'lax'
|
||||
COOKIE_SAME_SITE: 'lax',
|
||||
};
|
||||
|
||||
// Настройки API
|
||||
const API_CONFIG = {
|
||||
RATE_LIMIT: 100, // запросов в минуту
|
||||
TIMEOUT: 30000 // 30 секунд
|
||||
TIMEOUT: 30000, // 30 секунд
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
@@ -54,5 +54,5 @@ module.exports = {
|
||||
SENDER_TYPES,
|
||||
ERROR_CODES,
|
||||
SESSION_CONFIG,
|
||||
API_CONFIG
|
||||
API_CONFIG,
|
||||
};
|
||||
@@ -37,7 +37,8 @@ async function addUserIdentity(userId, provider, providerId) {
|
||||
);
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (error.code === '23505') { // Уникальное ограничение нарушено
|
||||
if (error.code === '23505') {
|
||||
// Уникальное ограничение нарушено
|
||||
return false;
|
||||
}
|
||||
throw error;
|
||||
@@ -49,5 +50,5 @@ module.exports = {
|
||||
isValidEmail,
|
||||
generateVerificationCode,
|
||||
checkUserIdentity,
|
||||
addUserIdentity
|
||||
addUserIdentity,
|
||||
};
|
||||
|
||||
4936
frontend/package-lock.json
generated
Normal file
4936
frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,8 @@
|
||||
"preview": "vite preview",
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --ignore-pattern 'node_modules/'",
|
||||
"lint:fix": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-pattern 'node_modules/'",
|
||||
"lint:style": "stylelint \"**/*.{vue,css}\"",
|
||||
"lint:style:fix": "stylelint \"**/*.{vue,css}\" --fix",
|
||||
"format": "prettier --write \"**/*.{js,vue,json,md}\"",
|
||||
"format:check": "prettier --check \"**/*.{js,vue,json,md}\""
|
||||
},
|
||||
@@ -34,9 +36,13 @@
|
||||
"eslint-plugin-prettier": "^5.2.3",
|
||||
"eslint-plugin-vue": "^9.32.0",
|
||||
"globals": "^16.0.0",
|
||||
"postcss-html": "^1.8.0",
|
||||
"prettier": "^3.5.3",
|
||||
"rollup": "^3.29.4",
|
||||
"rollup-plugin-polyfill-node": "^0.12.0",
|
||||
"stylelint": "^14.16.1",
|
||||
"stylelint-config-prettier": "^9.0.5",
|
||||
"stylelint-config-standard-vue": "^1.0.0",
|
||||
"vite": "^6.2.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -634,11 +634,17 @@
|
||||
const loadMessages = async (options = {}) => {
|
||||
const { silent = false, initial = false, authType = null } = options;
|
||||
|
||||
// Усиленная проверка для предотвращения параллельного выполнения
|
||||
if (messageLoading.value.isInProgress) {
|
||||
console.warn('[loadMessages] Выполнение уже идет, пропуск вызова.');
|
||||
return;
|
||||
}
|
||||
messageLoading.value.isInProgress = true; // Устанавливаем флаг НЕМЕДЛЕННО
|
||||
|
||||
if (messageLoading.value.isLoadingMore && !initial) return;
|
||||
|
||||
try {
|
||||
messageLoading.value.isLoadingMore = true;
|
||||
messageLoading.value.isInProgress = true;
|
||||
if (!silent) isLoading.value = true;
|
||||
|
||||
console.log(
|
||||
@@ -732,8 +738,8 @@
|
||||
removeFromStorage('guestId');
|
||||
}
|
||||
} else if (response.data.messages && response.data.messages.length) {
|
||||
// Иначе добавляем к существующим
|
||||
messages.value = [...messages.value, ...response.data.messages];
|
||||
// Иначе добавляем к существующим (В НАЧАЛО МАССИВА)
|
||||
messages.value = [...response.data.messages, ...messages.value];
|
||||
}
|
||||
|
||||
console.log(`Загружено ${messages.value.length} сообщений из истории`);
|
||||
|
||||
15
frontend/stylelint.config.cjs
Normal file
15
frontend/stylelint.config.cjs
Normal file
@@ -0,0 +1,15 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
// Используем стандартную конфигурацию для Vue (включает CSS и <style> в .vue)
|
||||
'stylelint-config-standard-vue',
|
||||
// Отключает правила Stylelint, конфликтующие с Prettier
|
||||
'stylelint-config-prettier',
|
||||
],
|
||||
// Здесь можно добавить или переопределить правила
|
||||
rules: {
|
||||
// Пример: можно отключить правило о пустой строке перед комментариями
|
||||
// 'comment-empty-line-before': null,
|
||||
// Пример: требовать нижний регистр для имен анимаций
|
||||
// 'keyframes-name-pattern': '^[a-z][a-z0-9-]*$',
|
||||
},
|
||||
};
|
||||
1672
frontend/yarn.lock
1672
frontend/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user