ваше сообщение коммита
This commit is contained in:
@@ -31,6 +31,10 @@ nano frontend/.env
|
|||||||
3. Запустите скрипт установки:
|
3. Запустите скрипт установки:
|
||||||
```bash
|
```bash
|
||||||
./setup.sh
|
./setup.sh
|
||||||
|
|
||||||
|
4. Выполните миграции изнутри контейнера backend:
|
||||||
|
```
|
||||||
|
docker exec dapp-backend yarn migrate
|
||||||
```
|
```
|
||||||
|
|
||||||
Скрипт автоматически:
|
Скрипт автоматически:
|
||||||
|
|||||||
@@ -64,6 +64,21 @@ class AuthService {
|
|||||||
|
|
||||||
if (userResult.rows.length > 0) {
|
if (userResult.rows.length > 0) {
|
||||||
const user = userResult.rows[0];
|
const user = userResult.rows[0];
|
||||||
|
|
||||||
|
// Проверяем роль администратора при каждой аутентификации
|
||||||
|
const isAdmin = await this.checkAdminRole(normalizedAddress);
|
||||||
|
|
||||||
|
// Если статус админа изменился, обновляем роль в базе данных
|
||||||
|
if (user.role === 'admin' && !isAdmin) {
|
||||||
|
await db.query('UPDATE users SET role = $1 WHERE id = $2', ['user', user.id]);
|
||||||
|
logger.info(`Updated user ${user.id} role to user (admin tokens no longer present)`);
|
||||||
|
return { userId: user.id, isAdmin: false };
|
||||||
|
} else if (user.role !== 'admin' && isAdmin) {
|
||||||
|
await db.query('UPDATE users SET role = $1 WHERE id = $2', ['admin', user.id]);
|
||||||
|
logger.info(`Updated user ${user.id} role to admin (admin tokens found)`);
|
||||||
|
return { userId: user.id, isAdmin: true };
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
isAdmin: user.role === 'admin'
|
isAdmin: user.role === 'admin'
|
||||||
@@ -86,6 +101,7 @@ class AuthService {
|
|||||||
|
|
||||||
// Проверяем, есть ли у пользователя роль админа
|
// Проверяем, есть ли у пользователя роль админа
|
||||||
const isAdmin = await this.checkAdminRole(normalizedAddress);
|
const isAdmin = await this.checkAdminRole(normalizedAddress);
|
||||||
|
logger.info(`New user ${userId} role check result: ${isAdmin ? 'admin' : 'user'}`);
|
||||||
|
|
||||||
// Если у пользователя есть админские токены, обновляем его роль
|
// Если у пользователя есть админские токены, обновляем его роль
|
||||||
if (isAdmin) {
|
if (isAdmin) {
|
||||||
@@ -95,7 +111,7 @@ class AuthService {
|
|||||||
|
|
||||||
return { userId, isAdmin };
|
return { userId, isAdmin };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error finding or creating user:', error);
|
logger.error('Error finding or creating user:', error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,13 +126,36 @@ class AuthService {
|
|||||||
|
|
||||||
logger.info(`Checking admin role for address: ${address}`);
|
logger.info(`Checking admin role for address: ${address}`);
|
||||||
let foundTokens = false;
|
let foundTokens = false;
|
||||||
|
let errorCount = 0;
|
||||||
const balances = {};
|
const balances = {};
|
||||||
|
const totalNetworks = ADMIN_CONTRACTS.length;
|
||||||
|
|
||||||
// Создаем массив промисов для параллельной проверки балансов
|
// Создаем массив промисов для параллельной проверки балансов
|
||||||
const checkPromises = ADMIN_CONTRACTS.map(async (contract) => {
|
const checkPromises = ADMIN_CONTRACTS.map(async (contract) => {
|
||||||
try {
|
try {
|
||||||
const provider = this.providers[contract.network];
|
const provider = this.providers[contract.network];
|
||||||
if (!provider) return null;
|
if (!provider) {
|
||||||
|
logger.error(`No provider available for network ${contract.network}`);
|
||||||
|
balances[contract.network] = 'Error: No provider';
|
||||||
|
errorCount++;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверяем доступность провайдера
|
||||||
|
try {
|
||||||
|
// Проверка доступности сети с таймаутом
|
||||||
|
const networkCheckPromise = provider.getNetwork();
|
||||||
|
const timeoutPromise = new Promise((_, reject) =>
|
||||||
|
setTimeout(() => reject(new Error('Network check timeout')), 3000)
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.race([networkCheckPromise, timeoutPromise]);
|
||||||
|
} catch (networkError) {
|
||||||
|
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(
|
const tokenContract = new ethers.Contract(
|
||||||
contract.address,
|
contract.address,
|
||||||
@@ -142,7 +181,7 @@ class AuthService {
|
|||||||
hasTokens: balance > 0
|
hasTokens: balance > 0
|
||||||
});
|
});
|
||||||
|
|
||||||
if (balance > 0) {
|
if (parseFloat(formattedBalance) > 0) {
|
||||||
logger.info(`Found admin tokens on ${contract.network}`);
|
logger.info(`Found admin tokens on ${contract.network}`);
|
||||||
foundTokens = true;
|
foundTokens = true;
|
||||||
}
|
}
|
||||||
@@ -152,9 +191,10 @@ class AuthService {
|
|||||||
logger.error(`Error checking balance in ${contract.network}:`, {
|
logger.error(`Error checking balance in ${contract.network}:`, {
|
||||||
address,
|
address,
|
||||||
contract: contract.address,
|
contract: contract.address,
|
||||||
error: error.message
|
error: error.message || 'Unknown error'
|
||||||
});
|
});
|
||||||
balances[contract.network] = 'Error';
|
balances[contract.network] = 'Error';
|
||||||
|
errorCount++;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -162,9 +202,15 @@ class AuthService {
|
|||||||
// Ждем выполнения всех проверок
|
// Ждем выполнения всех проверок
|
||||||
await Promise.all(checkPromises);
|
await Promise.all(checkPromises);
|
||||||
|
|
||||||
|
// Если все запросы завершились с ошибкой, считаем, что проверка не удалась
|
||||||
|
if (errorCount === totalNetworks) {
|
||||||
|
logger.error(`All network checks for ${address} failed. Cannot verify admin status.`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (foundTokens) {
|
if (foundTokens) {
|
||||||
logger.info(`Admin role summary for ${address}:`, {
|
logger.info(`Admin role summary for ${address}:`, {
|
||||||
networks: Object.keys(balances).filter(net => balances[net] > 0),
|
networks: Object.keys(balances).filter(net => balances[net] > 0 && balances[net] !== 'Error'),
|
||||||
balances
|
balances
|
||||||
});
|
});
|
||||||
logger.info(`Admin role granted for ${address}`);
|
logger.info(`Admin role granted for ${address}`);
|
||||||
@@ -203,6 +249,21 @@ class AuthService {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Проверяем доступность провайдера
|
||||||
|
try {
|
||||||
|
// Проверка доступности сети с таймаутом
|
||||||
|
const networkCheckPromise = provider.getNetwork();
|
||||||
|
const networkTimeoutPromise = new Promise((_, reject) =>
|
||||||
|
setTimeout(() => reject(new Error('Network check timeout')), timeout)
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.race([networkCheckPromise, networkTimeoutPromise]);
|
||||||
|
} catch (networkError) {
|
||||||
|
logger.error(`Provider for ${contract.network} is not available: ${networkError.message}`);
|
||||||
|
balances[contract.network] = '0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const tokenContract = new ethers.Contract(
|
const tokenContract = new ethers.Contract(
|
||||||
contract.address,
|
contract.address,
|
||||||
ERC20_ABI,
|
ERC20_ABI,
|
||||||
@@ -494,34 +555,62 @@ class AuthService {
|
|||||||
if (!address) return false;
|
if (!address) return false;
|
||||||
|
|
||||||
logger.info(`Checking admin tokens for address: ${address}`);
|
logger.info(`Checking admin tokens for address: ${address}`);
|
||||||
const isAdmin = await this.checkAdminRole(address);
|
|
||||||
|
|
||||||
// Обновляем роль пользователя в базе данных, если есть админские токены
|
try {
|
||||||
if (isAdmin) {
|
const isAdmin = await this.checkAdminRole(address);
|
||||||
try {
|
|
||||||
// Находим userId по адресу
|
|
||||||
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`,
|
|
||||||
[address.toLowerCase()]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (userResult.rows.length > 0) {
|
// Обновляем роль пользователя в базе данных, если есть админские токены
|
||||||
const userId = userResult.rows[0].id;
|
if (isAdmin) {
|
||||||
// Обновляем роль пользователя
|
try {
|
||||||
await db.query(
|
// Находим userId по адресу
|
||||||
'UPDATE users SET role = $1 WHERE id = $2',
|
const userResult = await db.query(`
|
||||||
['admin', userId]
|
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`,
|
||||||
|
[address.toLowerCase()]
|
||||||
);
|
);
|
||||||
logger.info(`Updated user ${userId} role to admin based on token holdings`);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
logger.error('Error updating user role:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return isAdmin;
|
if (userResult.rows.length > 0) {
|
||||||
|
const userId = userResult.rows[0].id;
|
||||||
|
// Обновляем роль пользователя
|
||||||
|
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) {
|
||||||
|
logger.error('Error updating user role:', error);
|
||||||
|
// Продолжаем выполнение, даже если обновление роли не удалось
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Если пользователь не является администратором, сбрасываем роль на "user", если она была "admin"
|
||||||
|
try {
|
||||||
|
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`,
|
||||||
|
[address.toLowerCase()]
|
||||||
|
);
|
||||||
|
|
||||||
|
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]
|
||||||
|
);
|
||||||
|
logger.info(`Reset user ${userId} role from admin to user (no tokens found)`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Error updating user role:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isAdmin;
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(`Error in checkAdminTokens: ${error.message}`);
|
||||||
|
return false; // При любой ошибке считаем, что пользователь не админ
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user