Описание изменений
This commit is contained in:
@@ -1,39 +0,0 @@
|
||||
const db = require('../db');
|
||||
const logger = require('../utils/logger');
|
||||
const authService = require('../services/auth-service');
|
||||
|
||||
/**
|
||||
* Проверяет токены всех пользователей и обновляет их роли
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function checkAllUsersTokens() {
|
||||
try {
|
||||
// Получаем всех пользователей с кошельками
|
||||
const walletUsers = await db.query(`
|
||||
SELECT u.id, ui.identity_value as address
|
||||
FROM users u
|
||||
JOIN user_identities ui ON u.id = ui.user_id
|
||||
WHERE ui.identity_type = 'wallet'
|
||||
`);
|
||||
|
||||
logger.info(`Checking tokens for ${walletUsers.rows.length} users`);
|
||||
|
||||
for (const user of walletUsers.rows) {
|
||||
try {
|
||||
// Используем существующий метод для проверки токенов и обновления роли
|
||||
const isAdmin = await authService.checkTokensAndUpdateRole(user.address);
|
||||
logger.info(`Updated user ${user.id} with address ${user.address}: admin=${isAdmin}`);
|
||||
} catch (error) {
|
||||
logger.error(`Error checking tokens for user ${user.id}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info('Token check completed');
|
||||
} catch (error) {
|
||||
logger.error(`Error checking all users tokens: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
checkAllUsersTokens
|
||||
};
|
||||
@@ -1,146 +0,0 @@
|
||||
const { ethers } = require('ethers');
|
||||
const db = require('../db');
|
||||
const logger = require('./logger');
|
||||
const authService = require('../services/auth-service');
|
||||
const { USER_ROLES, IDENTITY_TYPES } = require('./constants');
|
||||
|
||||
// Инициализация провайдера
|
||||
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL_ETH);
|
||||
|
||||
/**
|
||||
* Проверяет подпись сообщения
|
||||
* @param {string} nonce - Nonce для проверки
|
||||
* @param {string} signature - Подпись
|
||||
* @param {string} address - Адрес кошелька
|
||||
* @returns {Promise<boolean>} - Результат проверки
|
||||
*/
|
||||
async function verifySignature(nonce, signature, address) {
|
||||
try {
|
||||
// Создаем сообщение для проверки
|
||||
const message = `Подпишите это сообщение для аутентификации в DApp for Business. Nonce: ${nonce}`;
|
||||
|
||||
// Восстанавливаем адрес из подписи
|
||||
const recoveredAddress = ethers.verifyMessage(message, signature);
|
||||
|
||||
// Сравниваем адреса (приводим к нижнему регистру для надежности)
|
||||
return recoveredAddress.toLowerCase() === address.toLowerCase();
|
||||
} catch (error) {
|
||||
console.error('Error verifying signature:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет, является ли пользователь администратором
|
||||
* @param {string} address - Адрес кошелька
|
||||
* @returns {Promise<boolean>} - Является ли пользователь администратором
|
||||
*/
|
||||
async function checkUserRole(address) {
|
||||
try {
|
||||
// Проверяем наличие токенов администратора
|
||||
const isAdmin = await authService.checkAdminTokens(address);
|
||||
return isAdmin;
|
||||
} catch (error) {
|
||||
console.error('Error checking user role:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет доступ пользователя
|
||||
* @param {string} walletAddress - Адрес кошелька
|
||||
* @returns {Promise<Object>} - Информация о доступе
|
||||
*/
|
||||
async function checkAccess(walletAddress) {
|
||||
try {
|
||||
// Проверяем наличие токенов администратора
|
||||
const isAdmin = await authService.checkAdminTokens(walletAddress);
|
||||
|
||||
// Получаем или создаем пользователя
|
||||
const userId = await findOrCreateUser(walletAddress);
|
||||
|
||||
return {
|
||||
userId,
|
||||
isAdmin,
|
||||
hasAccess: true
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error(`Error checking access: ${error.message}`);
|
||||
return {
|
||||
hasAccess: false,
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Находит или создает пользователя по адресу кошелька
|
||||
* @param {string} address - Адрес кошелька
|
||||
* @returns {Promise<Object>} - ID пользователя и роль
|
||||
*/
|
||||
async function findOrCreateUser(address) {
|
||||
try {
|
||||
if (!address) {
|
||||
throw new Error('Address is required');
|
||||
}
|
||||
|
||||
const normalizedAddress = address.toLowerCase();
|
||||
|
||||
// Сначала проверяем в таблице users
|
||||
const userResult = await db.query(
|
||||
'SELECT id FROM users WHERE LOWER(address) = $1',
|
||||
[normalizedAddress]
|
||||
);
|
||||
|
||||
let userId;
|
||||
let isAdmin = false;
|
||||
|
||||
if (userResult.rows.length === 0) {
|
||||
// Если пользователь не найден, создаем его
|
||||
const roleResult = await db.query('SELECT id FROM roles WHERE name = $1', ['user']);
|
||||
if (roleResult.rows.length === 0) {
|
||||
throw new Error('Role "user" not found');
|
||||
}
|
||||
const roleId = roleResult.rows[0].id;
|
||||
|
||||
// Создаем пользователя
|
||||
const newUserResult = await db.query(
|
||||
'INSERT INTO users (address, role_id, created_at) VALUES ($1, $2, NOW()) RETURNING id',
|
||||
[normalizedAddress, roleId]
|
||||
);
|
||||
|
||||
userId = newUserResult.rows[0].id;
|
||||
|
||||
// Добавляем идентификатор кошелька
|
||||
await db.query(
|
||||
'INSERT INTO user_identities (user_id, identity_type, identity_value, created_at) VALUES ($1, $2, $3, NOW())',
|
||||
[userId, 'wallet', normalizedAddress]
|
||||
);
|
||||
} else {
|
||||
userId = userResult.rows[0].id;
|
||||
}
|
||||
|
||||
// Проверяем, является ли пользователь администратором
|
||||
isAdmin = await checkUserRole(normalizedAddress);
|
||||
|
||||
// Обновляем роль пользователя
|
||||
const roleNameToSet = isAdmin ? 'admin' : 'user';
|
||||
const roleToSetResult = await db.query('SELECT id FROM roles WHERE name = $1', [roleNameToSet]);
|
||||
if (roleToSetResult.rows.length > 0) {
|
||||
const roleIdToSet = roleToSetResult.rows[0].id;
|
||||
await db.query('UPDATE users SET role_id = $1 WHERE id = $2', [roleIdToSet, userId]);
|
||||
}
|
||||
|
||||
return { userId, isAdmin };
|
||||
} catch (error) {
|
||||
console.error('Error finding or creating user:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
verifySignature,
|
||||
checkAccess,
|
||||
findOrCreateUser,
|
||||
checkUserRole
|
||||
};
|
||||
@@ -1,105 +0,0 @@
|
||||
const { ethers } = require('ethers');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const logger = require('./logger');
|
||||
|
||||
// Инициализация провайдера
|
||||
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
|
||||
|
||||
// Путь к директории с ABI контрактов
|
||||
const contractsDir = path.join(__dirname, '../artifacts/contracts/AccessToken.sol');
|
||||
|
||||
// Получение ABI контракта
|
||||
const accessTokenJSON = require('../artifacts/contracts/AccessToken.sol/AccessToken.json');
|
||||
const accessTokenABI = accessTokenJSON.abi;
|
||||
|
||||
// Проверка, что ABI является массивом
|
||||
if (!Array.isArray(accessTokenABI)) {
|
||||
console.error('ABI is not an array:', accessTokenABI);
|
||||
// Если ABI не является массивом, создайте массив вручную
|
||||
const manualABI = [
|
||||
"function mintAccessToken(address to, uint8 role) public",
|
||||
"function checkRole(address user) public view returns (uint8)",
|
||||
"function revokeToken(uint256 tokenId) public",
|
||||
// Добавьте другие функции, которые вам нужны
|
||||
];
|
||||
|
||||
// Создание экземпляра контракта с ручным ABI
|
||||
const contractAddress = process.env.ACCESS_TOKEN_ADDRESS;
|
||||
const accessTokenContract = new ethers.Contract(contractAddress, manualABI, provider);
|
||||
|
||||
module.exports = {
|
||||
accessTokenContract,
|
||||
getContract,
|
||||
provider
|
||||
};
|
||||
} else {
|
||||
// Если ABI является массивом, используйте его
|
||||
const contractAddress = process.env.ACCESS_TOKEN_ADDRESS;
|
||||
const accessTokenContract = new ethers.Contract(contractAddress, accessTokenABI, provider);
|
||||
|
||||
module.exports = {
|
||||
accessTokenContract,
|
||||
getContract,
|
||||
provider
|
||||
};
|
||||
}
|
||||
|
||||
// Кэш для хранения экземпляров контрактов
|
||||
const contractsCache = {};
|
||||
|
||||
/**
|
||||
* Получает экземпляр контракта по его имени
|
||||
* @param {string} contractName - Имя контракта
|
||||
* @returns {Promise<ethers.Contract>} - Экземпляр контракта
|
||||
*/
|
||||
async function getContract(contractName) {
|
||||
try {
|
||||
console.log(`Getting contract: ${contractName}`);
|
||||
|
||||
// Проверяем, есть ли контракт в кэше
|
||||
if (contractsCache[contractName]) {
|
||||
console.log(`Using cached contract: ${contractName}`);
|
||||
return contractsCache[contractName];
|
||||
}
|
||||
|
||||
// Получаем адрес контракта из переменных окружения
|
||||
const contractAddress = process.env.ACCESS_TOKEN_ADDRESS; // или ACCESS_TOKEN_CONTRACT_ADDRESS
|
||||
|
||||
if (!contractAddress) {
|
||||
throw new Error(`Contract address for ${contractName} not found in environment variables`);
|
||||
}
|
||||
|
||||
// Путь к файлу с ABI контракта
|
||||
const abiPath = path.join(contractsDir, `${contractName}.json`);
|
||||
|
||||
// Проверяем, существует ли файл с ABI
|
||||
if (!fs.existsSync(abiPath)) {
|
||||
throw new Error(`ABI file for ${contractName} not found at ${abiPath}`);
|
||||
}
|
||||
|
||||
// Читаем ABI из файла
|
||||
const abiJson = fs.readFileSync(abiPath, 'utf8');
|
||||
const contractJSON = JSON.parse(abiJson);
|
||||
const abi = contractJSON.abi; // Получаем ABI из свойства abi
|
||||
|
||||
console.log(`ABI for ${contractName}:`, abi);
|
||||
|
||||
// Проверяем, что ABI является массивом
|
||||
if (!Array.isArray(abi)) {
|
||||
console.error(`ABI for ${contractName} is not an array:`, abi);
|
||||
throw new Error(`ABI for ${contractName} is not an array`);
|
||||
}
|
||||
|
||||
// Создаем экземпляр контракта
|
||||
const contract = new ethers.Contract(contractAddress, abi, provider);
|
||||
|
||||
// Сохраняем контракт в кэше
|
||||
contractsCache[contractName] = contract;
|
||||
|
||||
return contract;
|
||||
} catch (error) {
|
||||
logger.error(`Ошибка при получении контракта ${contractName}: ${error.message}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
const db = require('../db');
|
||||
const logger = require('./logger');
|
||||
|
||||
/**
|
||||
* Связывает идентификатор с пользователем
|
||||
* @param {number} userId - ID пользователя
|
||||
* @param {string} identityType - Тип идентификатора ('ethereum', 'telegram', 'email')
|
||||
* @param {string} identityValue - Значение идентификатора
|
||||
* @returns {Promise<boolean>} - Результат операции
|
||||
*/
|
||||
async function linkIdentity(userId, identityType, identityValue) {
|
||||
try {
|
||||
// Проверяем, существует ли уже такой идентификатор
|
||||
const existingResult = await db.query(
|
||||
'SELECT * FROM user_identities WHERE identity_type = $1 AND identity_value = $2',
|
||||
[identityType, identityValue]
|
||||
);
|
||||
|
||||
if (existingResult.rows.length > 0) {
|
||||
// Если идентификатор уже связан с другим пользователем, возвращаем ошибку
|
||||
if (existingResult.rows[0].user_id !== userId) {
|
||||
console.warn(`Identity ${identityType}:${identityValue} already linked to another user`);
|
||||
return false;
|
||||
}
|
||||
// Если идентификатор уже связан с этим пользователем, ничего не делаем
|
||||
return true;
|
||||
}
|
||||
|
||||
// Добавляем новую связь
|
||||
await db.query(
|
||||
'INSERT INTO user_identities (user_id, identity_type, identity_value, created_at) VALUES ($1, $2, $3, NOW())',
|
||||
[userId, identityType, identityValue]
|
||||
);
|
||||
|
||||
console.log(`Successfully linked ${identityType}:${identityValue} to user ${userId}`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error linking identity:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает ID пользователя по идентификатору
|
||||
* @param {string} identityType - Тип идентификатора ('ethereum', 'telegram', 'email')
|
||||
* @param {string} identityValue - Значение идентификатора
|
||||
* @returns {Promise<number|null>} - ID пользователя или null, если не найден
|
||||
*/
|
||||
async function getUserIdByIdentity(identityType, identityValue) {
|
||||
try {
|
||||
const result = await db.query(
|
||||
'SELECT user_id FROM user_identities WHERE identity_type = $1 AND identity_value = $2',
|
||||
[identityType, identityValue]
|
||||
);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return result.rows[0].user_id;
|
||||
} catch (error) {
|
||||
console.error('Error getting user ID by identity:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает все идентификаторы пользователя
|
||||
* @param {number} userId - ID пользователя
|
||||
* @returns {Promise<Array|null>} - Массив идентификаторов или null в случае ошибки
|
||||
*/
|
||||
async function getUserIdentities(userId) {
|
||||
try {
|
||||
const result = await db.query(
|
||||
'SELECT identity_type, identity_value FROM user_identities WHERE user_id = $1',
|
||||
[userId]
|
||||
);
|
||||
|
||||
return result.rows;
|
||||
} catch (error) {
|
||||
console.error('Error getting user identities:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
linkIdentity,
|
||||
getUserIdByIdentity,
|
||||
getUserIdentities,
|
||||
};
|
||||
Reference in New Issue
Block a user