Описание изменений
This commit is contained in:
@@ -4,43 +4,24 @@ const { Pool } = require('pg');
|
||||
const { requireAuth, requireAdmin } = require('../middleware/auth');
|
||||
const db = require('../db');
|
||||
const { ethers } = require('ethers');
|
||||
|
||||
// Подключение к БД
|
||||
const pool = new Pool({
|
||||
connectionString: process.env.DATABASE_URL,
|
||||
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false,
|
||||
});
|
||||
const authService = require('../services/auth-service');
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
// Проверка доступа
|
||||
router.get('/check', async (req, res) => {
|
||||
const walletAddress = req.headers['x-wallet-address'];
|
||||
|
||||
if (!walletAddress) {
|
||||
return res.status(400).json({ error: 'No wallet address provided' });
|
||||
}
|
||||
|
||||
try {
|
||||
// Проверяем наличие активного токена для адреса
|
||||
const result = await pool.query(
|
||||
'SELECT * FROM access_tokens WHERE wallet_address = $1 AND expires_at > NOW()',
|
||||
[walletAddress.toLowerCase()]
|
||||
);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
return res.json({ hasAccess: false });
|
||||
const { address } = req.query;
|
||||
|
||||
if (!address) {
|
||||
return res.status(400).json({ error: 'Address is required' });
|
||||
}
|
||||
|
||||
const token = result.rows[0];
|
||||
|
||||
res.json({
|
||||
hasAccess: true,
|
||||
tokenId: token.id,
|
||||
role: token.role,
|
||||
expiresAt: token.expires_at,
|
||||
});
|
||||
|
||||
const isAdmin = await authService.checkAdminToken(address);
|
||||
|
||||
res.json({ isAdmin });
|
||||
} catch (error) {
|
||||
console.error('Access check error:', error);
|
||||
res.status(500).json({ error: error.message });
|
||||
logger.error(`Error checking access: ${error.message}`);
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -63,40 +44,14 @@ router.get('/admin-only', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Получение списка токенов
|
||||
// Получение всех токенов доступа
|
||||
router.get('/tokens', async (req, res) => {
|
||||
const walletAddress = req.headers['x-wallet-address'];
|
||||
|
||||
if (!walletAddress) {
|
||||
return res.status(400).json({ error: 'No wallet address provided' });
|
||||
}
|
||||
|
||||
try {
|
||||
// Проверяем права администратора
|
||||
const adminCheck = await pool.query(
|
||||
'SELECT * FROM access_tokens WHERE wallet_address = $1 AND role = $2 AND expires_at > NOW()',
|
||||
[walletAddress.toLowerCase(), 'ADMIN']
|
||||
);
|
||||
|
||||
if (adminCheck.rows.length === 0) {
|
||||
return res.status(403).json({ error: 'Access denied' });
|
||||
}
|
||||
|
||||
// Получаем список всех токенов
|
||||
const result = await pool.query('SELECT * FROM access_tokens ORDER BY created_at DESC');
|
||||
|
||||
res.json(
|
||||
result.rows.map((token) => ({
|
||||
id: token.id,
|
||||
walletAddress: token.wallet_address,
|
||||
role: token.role,
|
||||
createdAt: token.created_at,
|
||||
expiresAt: token.expires_at,
|
||||
}))
|
||||
);
|
||||
const tokens = await authService.getAllTokens();
|
||||
res.json(tokens);
|
||||
} catch (error) {
|
||||
console.error('Tokens list error:', error);
|
||||
res.status(500).json({ error: error.message });
|
||||
logger.error(`Error getting tokens: ${error.message}`);
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -110,12 +65,9 @@ router.post('/tokens', async (req, res) => {
|
||||
|
||||
try {
|
||||
// Проверяем права администратора
|
||||
const adminCheck = await pool.query(
|
||||
'SELECT * FROM access_tokens WHERE wallet_address = $1 AND role = $2 AND expires_at > NOW()',
|
||||
[walletAddress.toLowerCase(), 'ADMIN']
|
||||
);
|
||||
const isAdmin = await authService.checkAdminToken(walletAddress);
|
||||
|
||||
if (adminCheck.rows.length === 0) {
|
||||
if (!isAdmin) {
|
||||
return res.status(403).json({ error: 'Access denied' });
|
||||
}
|
||||
|
||||
@@ -130,7 +82,7 @@ router.post('/tokens', async (req, res) => {
|
||||
expiresAt.setDate(expiresAt.getDate() + parseInt(expiresInDays));
|
||||
|
||||
// Создаем токен
|
||||
const result = await pool.query(
|
||||
const result = await db.query(
|
||||
'INSERT INTO access_tokens (wallet_address, role, expires_at) VALUES ($1, $2, $3) RETURNING *',
|
||||
[targetAddress.toLowerCase(), role, expiresAt]
|
||||
);
|
||||
@@ -158,19 +110,16 @@ router.delete('/tokens/:id', async (req, res) => {
|
||||
|
||||
try {
|
||||
// Проверяем права администратора
|
||||
const adminCheck = await pool.query(
|
||||
'SELECT * FROM access_tokens WHERE wallet_address = $1 AND role = $2 AND expires_at > NOW()',
|
||||
[walletAddress.toLowerCase(), 'ADMIN']
|
||||
);
|
||||
const isAdmin = await authService.checkAdminToken(walletAddress);
|
||||
|
||||
if (adminCheck.rows.length === 0) {
|
||||
if (!isAdmin) {
|
||||
return res.status(403).json({ error: 'Access denied' });
|
||||
}
|
||||
|
||||
const { id } = req.params;
|
||||
|
||||
// Удаляем токен
|
||||
await pool.query('DELETE FROM access_tokens WHERE id = $1', [id]);
|
||||
await db.query('DELETE FROM access_tokens WHERE id = $1', [id]);
|
||||
|
||||
res.json({ success: true });
|
||||
} catch (error) {
|
||||
@@ -182,118 +131,95 @@ router.delete('/tokens/:id', async (req, res) => {
|
||||
// Получение информации о роли текущего пользователя
|
||||
router.get('/role', requireAuth, async (req, res) => {
|
||||
try {
|
||||
const address = req.session.address.toLowerCase();
|
||||
|
||||
const result = await db.query(
|
||||
'SELECT r.name as role FROM users u JOIN roles r ON u.role_id = r.id WHERE LOWER(u.address) = $1',
|
||||
[address]
|
||||
);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
return res.status(404).json({ error: 'Пользователь не найден' });
|
||||
}
|
||||
|
||||
return res.json({ role: result.rows[0].role });
|
||||
const role = await authService.getUserRole(req.user.id);
|
||||
return res.json({ role });
|
||||
} catch (error) {
|
||||
console.error('Ошибка при получении роли:', error);
|
||||
logger.error('Ошибка при получении роли:', error);
|
||||
return res.status(500).json({ error: 'Внутренняя ошибка сервера' });
|
||||
}
|
||||
});
|
||||
|
||||
// Получение списка всех пользователей (только для администраторов)
|
||||
router.get('/users', requireAdmin, async (req, res) => {
|
||||
router.get('/users', requireAuth, requireAdmin, async (req, res) => {
|
||||
try {
|
||||
const result = await db.query(
|
||||
'SELECT u.id, u.wallet_address, r.name as role, u.created_at FROM users u JOIN roles r ON u.role_id = r.id'
|
||||
);
|
||||
const result = await db.query(`
|
||||
SELECT u.id, ui.identity_value as wallet_address, r.name as role, u.created_at
|
||||
FROM users u
|
||||
JOIN roles r ON u.role_id = r.id
|
||||
LEFT JOIN user_identities ui ON u.id = ui.user_id AND ui.identity_type = 'wallet'
|
||||
`);
|
||||
|
||||
return res.json(result.rows);
|
||||
} catch (error) {
|
||||
console.error('Ошибка при получении списка пользователей:', error);
|
||||
logger.error('Ошибка при получении списка пользователей:', error);
|
||||
return res.status(500).json({ error: 'Внутренняя ошибка сервера' });
|
||||
}
|
||||
});
|
||||
|
||||
// Изменение роли пользователя (только для администраторов)
|
||||
router.post('/users/:userId/role', requireAdmin, async (req, res) => {
|
||||
// Обновление роли пользователя
|
||||
router.post('/update-role', async (req, res) => {
|
||||
try {
|
||||
const { userId } = req.params;
|
||||
const { role } = req.body;
|
||||
|
||||
if (!role || !['admin', 'user'].includes(role)) {
|
||||
return res.status(400).json({ error: 'Некорректная роль' });
|
||||
const { userId, role } = req.body;
|
||||
|
||||
if (!userId || !role) {
|
||||
return res.status(400).json({ error: 'User ID and role are required' });
|
||||
}
|
||||
|
||||
const success = await authService.updateUserRole(userId, role);
|
||||
|
||||
if (success) {
|
||||
res.json({ success: true });
|
||||
} else {
|
||||
res.status(400).json({ error: 'Failed to update role' });
|
||||
}
|
||||
|
||||
await db.query(
|
||||
'UPDATE users SET role_id = (SELECT id FROM roles WHERE name = $1) WHERE id = $2',
|
||||
[role, userId]
|
||||
);
|
||||
|
||||
return res.json({ success: true });
|
||||
} catch (error) {
|
||||
console.error('Ошибка при изменении роли пользователя:', error);
|
||||
return res.status(500).json({ error: 'Внутренняя ошибка сервера' });
|
||||
logger.error(`Error updating role: ${error.message}`);
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
});
|
||||
|
||||
// Получение информации о токенах доступа текущего пользователя
|
||||
router.get('/tokens', requireAuth, async (req, res) => {
|
||||
// Связывание нового идентификатора с аккаунтом
|
||||
router.post('/link-identity', requireAuth, async (req, res) => {
|
||||
try {
|
||||
// Логирование для отладки
|
||||
console.log('GET /api/access/tokens запрос получен');
|
||||
console.log('Сессия пользователя:', req.session);
|
||||
|
||||
// Получаем адрес из сессии, а не из заголовков
|
||||
if (!req.session || !req.session.address) {
|
||||
return res.status(400).json({ error: 'No wallet address in session' });
|
||||
const { identityType, identityValue } = req.body;
|
||||
|
||||
if (!identityType || !identityValue) {
|
||||
return res.status(400).json({ error: 'Отсутствуют обязательные поля' });
|
||||
}
|
||||
|
||||
const address = req.session.address.toLowerCase();
|
||||
|
||||
// Используем правильное имя таблицы и полей
|
||||
const result = await db.query(
|
||||
'SELECT id, wallet_address, role, created_at, expires_at FROM access_tokens WHERE LOWER(wallet_address) = $1',
|
||||
[address]
|
||||
);
|
||||
|
||||
return res.json(result.rows);
|
||||
} catch (error) {
|
||||
console.error('Ошибка при получении токенов:', error);
|
||||
res.status(500).json({ error: 'Ошибка сервера' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/mint', requireAuth, requireAdmin, async (req, res) => {
|
||||
try {
|
||||
// Логирование для отладки
|
||||
console.log('POST /api/access/mint запрос получен');
|
||||
console.log('Данные запроса:', req.body);
|
||||
|
||||
const { walletAddress, role, expiresInDays } = req.body;
|
||||
|
||||
if (!walletAddress || !role || !expiresInDays) {
|
||||
return res.status(400).json({ error: 'Missing required fields' });
|
||||
|
||||
// Проверяем, не привязан ли уже этот идентификатор к другому пользователю
|
||||
const existingUserId = await authService.getUserIdByIdentity(identityType, identityValue);
|
||||
|
||||
if (existingUserId && existingUserId !== req.user.id) {
|
||||
return res.status(400).json({ error: 'Этот идентификатор уже привязан к другому аккаунту' });
|
||||
}
|
||||
|
||||
// Вычисляем дату истечения
|
||||
const expiresAt = new Date();
|
||||
expiresAt.setDate(expiresAt.getDate() + parseInt(expiresInDays));
|
||||
|
||||
// Создаем токен
|
||||
const result = await pool.query(
|
||||
'INSERT INTO access_tokens (wallet_address, role, expires_at) VALUES ($1, $2, $3) RETURNING *',
|
||||
[walletAddress.toLowerCase(), role, expiresAt]
|
||||
);
|
||||
|
||||
|
||||
// Добавляем новый идентификатор
|
||||
if (!existingUserId) {
|
||||
await db.query(
|
||||
'INSERT INTO user_identities (user_id, identity_type, identity_value, created_at) VALUES ($1, $2, $3, NOW())',
|
||||
[req.user.id, identityType, identityValue]
|
||||
);
|
||||
}
|
||||
|
||||
// Если добавлен кошелек, проверяем токены
|
||||
if (identityType === 'wallet') {
|
||||
await authService.checkTokensAndUpdateRole(identityValue);
|
||||
}
|
||||
|
||||
// Получаем все идентификаторы пользователя
|
||||
const identities = await authService.getAllUserIdentities(req.user.id);
|
||||
|
||||
// Получаем текущую роль
|
||||
const isAdmin = await authService.isAdmin(req.user.id);
|
||||
|
||||
res.json({
|
||||
id: result.rows[0].id,
|
||||
walletAddress: result.rows[0].wallet_address,
|
||||
role: result.rows[0].role,
|
||||
createdAt: result.rows[0].created_at,
|
||||
expiresAt: result.rows[0].expires_at,
|
||||
success: true,
|
||||
identities,
|
||||
isAdmin
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Ошибка при создании токена:', error);
|
||||
logger.error(`Link identity error: ${error.message}`);
|
||||
res.status(500).json({ error: 'Ошибка сервера' });
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user