Тестовый коммит после удаления husky

This commit is contained in:
2025-03-05 01:02:09 +03:00
parent 97ca5e4b64
commit 3157ad0cd9
118 changed files with 8177 additions and 8530 deletions

View File

@@ -4,14 +4,9 @@ const path = require('path');
const packageJson = require('../package.json');
const dependencies = packageJson.dependencies || {};
const requiredDependencies = [
'express-rate-limit',
'winston',
'helmet',
'csurf'
];
const requiredDependencies = ['express-rate-limit', 'winston', 'helmet', 'csurf'];
const missingDependencies = requiredDependencies.filter(dep => !dependencies[dep]);
const missingDependencies = requiredDependencies.filter((dep) => !dependencies[dep]);
if (missingDependencies.length > 0) {
console.error('Missing dependencies:', missingDependencies);
@@ -19,4 +14,4 @@ if (missingDependencies.length > 0) {
process.exit(1);
}
console.log('All required dependencies are installed.');
console.log('All required dependencies are installed.');

View File

@@ -0,0 +1,125 @@
const fs = require('fs');
const path = require('path');
const { promisify } = require('util');
const readFile = promisify(fs.readFile);
const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat);
// Паттерны для поиска несовместимых конструкций ethers.js v5
const patterns = [
'ethers.providers.JsonRpcProvider',
'ethers.providers.Web3Provider',
'ethers.utils.parseEther',
'ethers.utils.formatEther',
'ethers.utils.formatUnits',
'ethers.utils.parseUnits',
'ethers.utils.verifyMessage',
'ethers.utils.keccak256',
'ethers.utils.toUtf8Bytes',
'ethers.utils.arrayify',
'ethers.utils.hexlify',
'ethers.BigNumber.from',
'ethers.constants.Zero',
'ethers.constants.One',
'ethers.constants.Two',
'ethers.constants.MaxUint256',
'ethers.constants.AddressZero',
'ethers.constants.HashZero',
];
// Соответствующие замены для ethers.js v6.x
const replacements = [
'ethers.JsonRpcProvider',
'ethers.BrowserProvider',
'ethers.parseEther',
'ethers.formatEther',
'ethers.formatUnits',
'ethers.parseUnits',
'ethers.verifyMessage',
'ethers.keccak256',
'ethers.toUtf8Bytes',
'ethers.getBytes',
'ethers.hexlify',
'ethers.getBigInt',
'ethers.ZeroAddress',
'ethers.ZeroAddress',
'ethers.ZeroAddress',
'ethers.MaxUint256',
'ethers.ZeroAddress',
'ethers.ZeroHash',
];
// Функция для рекурсивного обхода директории
async function walkDir(dir, fileList = []) {
const files = await readdir(dir);
for (const file of files) {
const filePath = path.join(dir, file);
const fileStat = await stat(filePath);
if (fileStat.isDirectory()) {
// Пропускаем node_modules и .git
if (file !== 'node_modules' && file !== '.git') {
fileList = await walkDir(filePath, fileList);
}
} else if (file.endsWith('.js')) {
fileList.push(filePath);
}
}
return fileList;
}
// Функция для проверки файла
async function checkFile(filePath) {
try {
if (filePath.includes('check-ethers-v6-compatibility.js')) {
return false; // Пропускаем проверку самого скрипта
}
const content = await readFile(filePath, 'utf8');
let hasIssues = false;
for (let i = 0; i < patterns.length; i++) {
if (content.includes(patterns[i])) {
console.log(`\x1b[33mПроблема в файле ${filePath}:\x1b[0m`);
console.log(` Найдено: \x1b[31m${patterns[i]}\x1b[0m`);
console.log(` Заменить на: \x1b[32m${replacements[i]}\x1b[0m`);
hasIssues = true;
}
}
return hasIssues;
} catch (error) {
console.error(`Ошибка при проверке файла ${filePath}:`, error);
return false;
}
}
// Основная функция
async function main() {
try {
console.log('Проверка совместимости с ethers.js v6.x...');
const files = await walkDir(path.resolve(__dirname, '..'));
let issuesFound = false;
for (const file of files) {
const hasIssues = await checkFile(file);
if (hasIssues) {
issuesFound = true;
}
}
if (!issuesFound) {
console.log('\x1b[32mПроблем не найдено. Код совместим с ethers.js v6.x\x1b[0m');
} else {
console.log('\n\x1b[33mНайдены проблемы совместимости с ethers.js v6.x\x1b[0m');
console.log('Пожалуйста, обновите код в соответствии с рекомендациями выше.');
}
} catch (error) {
console.error('Ошибка при проверке совместимости:', error);
}
}
main();

View File

@@ -0,0 +1,34 @@
const axios = require('axios');
async function checkOllamaModels() {
try {
console.log('Проверка доступных моделей Ollama...');
const baseUrl = process.env.OLLAMA_BASE_URL || 'http://localhost:11434';
const response = await axios.get(`${baseUrl}/api/tags`, {
timeout: 5000, // 5 секунд таймаут
});
if (response.status === 200 && response.data && response.data.models) {
console.log('\nДоступные модели Ollama:');
console.log('------------------------');
response.data.models.forEach((model) => {
console.log(`- ${model.name}`);
});
console.log('\nДля использования конкретной модели, укажите ее в .env файле:');
console.log('OLLAMA_EMBEDDINGS_MODEL=mistral');
console.log('OLLAMA_MODEL=mistral');
} else {
console.log('Не удалось получить список моделей');
}
} catch (error) {
console.error('Ошибка при проверке моделей Ollama:', error.message);
console.log('\nУбедитесь, что Ollama запущен. Вы можете запустить его командой:');
console.log('ollama serve');
}
}
// Запускаем проверку
checkOllamaModels();

View File

@@ -1,34 +1,31 @@
const hre = require("hardhat");
const hre = require('hardhat');
async function main() {
const accessToken = await hre.ethers.getContractAt(
"AccessToken",
"0xF352c498cF0857F472dC473E4Dd39551E79B1063"
'AccessToken',
'0xF352c498cF0857F472dC473E4Dd39551E79B1063'
);
const owner = await accessToken.owner();
console.log("Contract owner:", owner);
console.log('Contract owner:', owner);
// Проверяем все токены и их владельцев
console.log("\nAll tokens:");
console.log('\nAll tokens:');
for (let i = 1; i <= 10; i++) {
try {
const tokenOwner = await accessToken.ownerOf(i);
console.log(`Token ${i} owner: ${tokenOwner}`);
} catch (error) {
if (!error.message.includes("invalid token ID")) {
if (!error.message.includes('invalid token ID')) {
console.log(`Token ${i} error:`, error.message);
}
}
}
// Проверяем активные токены для всех известных адресов
const addresses = [
owner,
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
];
const addresses = [owner, '0x70997970C51812dc3A010C7d01b50e0d17dc79C8'];
console.log("\nActive tokens:");
console.log('\nActive tokens:');
for (const address of addresses) {
const activeToken = await accessToken.activeTokens(address);
console.log(`${address}: Token ${activeToken.toString()}`);
@@ -40,4 +37,4 @@ main()
.catch((error) => {
console.error(error);
process.exit(1);
});
});

View File

@@ -0,0 +1,21 @@
const { checkAllUsersTokens } = require('../utils/access-check');
const logger = require('../utils/logger');
async function main() {
logger.info('Starting token balance check for all users');
try {
await checkAllUsersTokens();
logger.info('Token balance check completed successfully');
} catch (error) {
logger.error(`Error during token balance check: ${error.message}`);
}
}
// Запуск скрипта
main()
.then(() => process.exit(0))
.catch(error => {
logger.error(`Unhandled error: ${error.message}`);
process.exit(1);
});

View File

@@ -1,42 +1,41 @@
const hre = require("hardhat");
const hre = require('hardhat');
async function main() {
const accessToken = await hre.ethers.getContractAt(
"AccessToken",
"0xF352c498cF0857F472dC473E4Dd39551E79B1063"
'AccessToken',
'0xF352c498cF0857F472dC473E4Dd39551E79B1063'
);
const moderatorAddress = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8";
const moderatorAddress = '0x70997970C51812dc3A010C7d01b50e0d17dc79C8';
try {
console.log("\nMinting moderator token...");
console.log('\nMinting moderator token...');
const mintTx = await accessToken.mintAccessToken(moderatorAddress, 1); // MODERATOR
console.log("Waiting for transaction:", mintTx.hash);
console.log('Waiting for transaction:', mintTx.hash);
await mintTx.wait();
console.log("Moderator token minted");
console.log('Moderator token minted');
// Проверяем результат
const activeToken = await accessToken.activeTokens(moderatorAddress);
console.log(`Moderator's active token: ${activeToken}`);
const role = await accessToken.checkRole(moderatorAddress);
console.log(`Moderator role: ${["ADMIN", "MODERATOR", "SUPPORT"][role]}`);
console.log(`Moderator role: ${['ADMIN', 'MODERATOR', 'SUPPORT'][role]}`);
} catch (error) {
console.log("Moderator token minting error:", error.message);
console.log('Moderator token minting error:', error.message);
}
// Проверяем все активные токены
console.log("\nAll active tokens:");
const addresses = [
await accessToken.owner(),
moderatorAddress
];
console.log('\nAll active tokens:');
const addresses = [await accessToken.owner(), moderatorAddress];
for (const address of addresses) {
try {
const activeToken = await accessToken.activeTokens(address);
const role = await accessToken.checkRole(address);
console.log(`${address}: Token ${activeToken}, Role: ${["ADMIN", "MODERATOR", "SUPPORT"][role]}`);
console.log(
`${address}: Token ${activeToken}, Role: ${['ADMIN', 'MODERATOR', 'SUPPORT'][role]}`
);
} catch (error) {
console.log(`${address}: ${error.message}`);
}
@@ -46,6 +45,6 @@ async function main() {
main()
.then(() => process.exit(0))
.catch((error) => {
console.error("Script error:", error);
console.error('Script error:', error);
process.exit(1);
});
});

View File

@@ -1,18 +1,18 @@
const hre = require("hardhat");
const hre = require('hardhat');
async function main() {
const AccessToken = await hre.ethers.getContractFactory("AccessToken");
const AccessToken = await hre.ethers.getContractFactory('AccessToken');
const accessToken = await AccessToken.deploy();
await accessToken.waitForDeployment();
const address = await accessToken.getAddress();
console.log("AccessToken deployed to:", address);
console.log('AccessToken deployed to:', address);
// Создаем первый админский токен для владельца контракта
const [owner] = await hre.ethers.getSigners();
const tx = await accessToken.mintAccessToken(owner.address, 0); // 0 = ADMIN
await tx.wait();
console.log("Admin token minted for:", owner.address);
console.log('Admin token minted for:', owner.address);
}
main()
@@ -20,4 +20,4 @@ main()
.catch((error) => {
console.error(error);
process.exit(1);
});
});

View File

@@ -1,17 +1,17 @@
const hre = require("hardhat");
const hre = require('hardhat');
async function main() {
console.log("Начинаем деплой контракта...");
console.log('Начинаем деплой контракта...');
// Получаем контракт
const MyContract = await hre.ethers.getContractFactory("MyContract");
const MyContract = await hre.ethers.getContractFactory('MyContract');
// Деплоим контракт
const myContract = await MyContract.deploy();
await myContract.waitForDeployment();
const address = await myContract.getAddress();
console.log("Контракт развернут по адресу:", address);
console.log('Контракт развернут по адресу:', address);
}
main()
@@ -19,4 +19,4 @@ main()
.catch((error) => {
console.error(error);
process.exit(1);
});
});

View File

@@ -5,20 +5,20 @@ dotenv.config();
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false,
});
async function initDb() {
try {
console.log('Инициализация базы данных...');
// Добавляем тестового пользователя
await pool.query(`
INSERT INTO users (address, is_admin)
VALUES ('0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b', TRUE)
ON CONFLICT (address) DO NOTHING
`);
// Добавляем тестовую доску
await pool.query(`
INSERT INTO kanban_boards (title, description, owner_id, is_public)
@@ -30,17 +30,18 @@ async function initDb() {
)
ON CONFLICT DO NOTHING
`);
// Получаем ID доски
const boardResult = await pool.query(`
SELECT id FROM kanban_boards WHERE title = 'Тестовая доска' LIMIT 1
`);
if (boardResult.rows.length > 0) {
const boardId = boardResult.rows[0].id;
// Добавляем тестовые колонки
await pool.query(`
await pool.query(
`
INSERT INTO kanban_columns (board_id, title, position)
VALUES
($1, 'Backlog', 0),
@@ -48,9 +49,11 @@ async function initDb() {
($1, 'Review', 2),
($1, 'Done', 3)
ON CONFLICT DO NOTHING
`, [boardId]);
`,
[boardId]
);
}
console.log('База данных инициализирована успешно');
} catch (error) {
console.error('Ошибка при инициализации базы данных:', error);
@@ -59,4 +62,4 @@ async function initDb() {
}
}
initDb();
initDb();

View File

@@ -1,13 +1,13 @@
const hre = require("hardhat");
const hre = require('hardhat');
async function main() {
const accessToken = await hre.ethers.getContractAt(
"AccessToken",
"0xF352c498cF0857F472dC473E4Dd39551E79B1063"
'AccessToken',
'0xF352c498cF0857F472dC473E4Dd39551E79B1063'
);
const owner = await accessToken.owner();
console.log("Contract owner:", owner);
console.log('Contract owner:', owner);
// Создаем админский токен для владельца
try {
@@ -16,34 +16,34 @@ async function main() {
console.log(`Admin token minted for ${owner}`);
const role = await accessToken.checkRole(owner);
console.log("Owner role:", ["ADMIN", "MODERATOR", "SUPPORT"][role]);
console.log('Owner role:', ['ADMIN', 'MODERATOR', 'SUPPORT'][role]);
} catch (error) {
console.log("Admin token minting error:", error.message);
console.log('Admin token minting error:', error.message);
}
// Создаем тестовый токен модератора
const moderatorAddress = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"; // Тестовый адрес модератора
const moderatorAddress = '0x70997970C51812dc3A010C7d01b50e0d17dc79C8'; // Тестовый адрес модератора
try {
const tx = await accessToken.mintAccessToken(moderatorAddress, 1); // 1 = MODERATOR
await tx.wait();
console.log(`Moderator token minted for ${moderatorAddress}`);
const role = await accessToken.checkRole(moderatorAddress);
console.log("Moderator role:", ["ADMIN", "MODERATOR", "SUPPORT"][role]);
console.log('Moderator role:', ['ADMIN', 'MODERATOR', 'SUPPORT'][role]);
} catch (error) {
console.log("Moderator token minting error:", error.message);
console.log('Moderator token minting error:', error.message);
}
// Проверяем все токены
console.log("\nChecking all tokens:");
console.log('\nChecking all tokens:');
for (let i = 1; i <= 5; i++) {
try {
const owner = await accessToken.ownerOf(i);
const role = await accessToken.checkRole(owner);
console.log(`Token ${i}: Owner ${owner}, Role: ${["ADMIN", "MODERATOR", "SUPPORT"][role]}`);
console.log(`Token ${i}: Owner ${owner}, Role: ${['ADMIN', 'MODERATOR', 'SUPPORT'][role]}`);
} catch (error) {
// Пропускаем несуществующие токены
if (!error.message.includes("nonexistent token")) {
if (!error.message.includes('nonexistent token')) {
console.log(`Token ${i} error:`, error.message);
}
}
@@ -55,4 +55,4 @@ main()
.catch((error) => {
console.error(error);
process.exit(1);
});
});

View File

@@ -1,72 +0,0 @@
const hre = require("hardhat");
async function main() {
const accessToken = await hre.ethers.getContractAt(
"AccessToken",
"0xF352c498cF0857F472dC473E4Dd39551E79B1063" // Адрес нашего контракта
);
// Проверим текущего владельца
const owner = await accessToken.owner();
console.log("Contract owner:", owner);
// Проверим роль владельца
try {
const ownerRole = await accessToken.checkRole(owner);
console.log("Owner role:", ["ADMIN", "MODERATOR", "SUPPORT"][ownerRole]);
} catch (error) {
console.log("Owner role check error:", error.message);
}
// Создадим токен модератора для тестового адреса
const moderatorAddress = "0xF45aa4917b3775bA37f48Aeb3dc1a943561e9e0B";
try {
const tx = await accessToken.mintAccessToken(moderatorAddress, 1); // 1 = MODERATOR
await tx.wait();
console.log(`Moderator token minted for ${moderatorAddress}`);
// Проверим роль модератора
const modRole = await accessToken.checkRole(moderatorAddress);
console.log("Moderator role:", ["ADMIN", "MODERATOR", "SUPPORT"][modRole]);
} catch (error) {
console.log("Moderator token minting error:", error.message);
}
// Получим все активные токены (с ограничением по блокам)
const currentBlock = await hre.ethers.provider.getBlockNumber();
const fromBlock = currentBlock - 1000; // Последние 1000 блоков
const filter = accessToken.filters.Transfer(null, null, null);
const events = await accessToken.queryFilter(filter, fromBlock);
console.log("\nActive tokens (last 1000 blocks):");
for (let event of events) {
if (event.args.from === "0x0000000000000000000000000000000000000000") {
console.log(`Token ID: ${event.args.tokenId}, Owner: ${event.args.to}`);
try {
const role = await accessToken.checkRole(event.args.to);
console.log(`Role: ${["ADMIN", "MODERATOR", "SUPPORT"][role]}`);
} catch (error) {
console.log("Role check error:", error.message);
}
}
}
// Альтернативный способ - проверить конкретный токен
console.log("\nChecking specific tokens:");
for (let i = 1; i <= 2; i++) {
try {
const owner = await accessToken.ownerOf(i);
const role = await accessToken.checkRole(owner);
console.log(`Token ${i}: Owner ${owner}, Role: ${["ADMIN", "MODERATOR", "SUPPORT"][role]}`);
} catch (error) {
console.log(`Token ${i} not found or error:`, error.message);
}
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

View File

@@ -1,9 +1,9 @@
const hre = require("hardhat");
const hre = require('hardhat');
async function main() {
const accessToken = await hre.ethers.getContractAt(
"AccessToken",
"0xF352c498cF0857F472dC473E4Dd39551E79B1063"
'AccessToken',
'0xF352c498cF0857F472dC473E4Dd39551E79B1063'
);
// Отзываем все токены от 1 до 3
@@ -23,4 +23,4 @@ main()
.catch((error) => {
console.error(error);
process.exit(1);
});
});

View File

@@ -6,13 +6,13 @@ require('dotenv').config();
// Подключение к БД
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false,
});
async function runMigrations() {
try {
console.log('Запуск миграций...');
// Создаем таблицу для отслеживания миграций, если её нет
await pool.query(`
CREATE TABLE IF NOT EXISTS migrations (
@@ -21,41 +21,39 @@ async function runMigrations() {
applied_at TIMESTAMP DEFAULT NOW()
)
`);
// Получаем список уже примененных миграций
const { rows } = await pool.query('SELECT name FROM migrations');
const appliedMigrations = rows.map(row => row.name);
const appliedMigrations = rows.map((row) => row.name);
// Получаем список файлов миграций
const migrationsDir = path.join(__dirname, '../migrations');
const migrationFiles = fs.readdirSync(migrationsDir)
.filter(file => file.endsWith('.sql'))
const migrationFiles = fs
.readdirSync(migrationsDir)
.filter((file) => file.endsWith('.sql'))
.sort(); // Сортируем файлы по имени
// Применяем миграции, которые еще не были применены
for (const file of migrationFiles) {
if (!appliedMigrations.includes(file)) {
console.log(`Применение миграции: ${file}`);
// Читаем содержимое файла миграции
const filePath = path.join(migrationsDir, file);
const sql = fs.readFileSync(filePath, 'utf8');
// Выполняем SQL-запросы из файла
await pool.query(sql);
// Записываем информацию о примененной миграции
await pool.query(
'INSERT INTO migrations (name) VALUES ($1)',
[file]
);
await pool.query('INSERT INTO migrations (name) VALUES ($1)', [file]);
console.log(`Миграция ${file} успешно применена`);
} else {
console.log(`Миграция ${file} уже применена`);
}
}
console.log('Все миграции успешно применены');
} catch (error) {
console.error('Ошибка при выполнении миграций:', error);
@@ -65,4 +63,4 @@ async function runMigrations() {
}
}
runMigrations();
runMigrations();

View File

@@ -0,0 +1,53 @@
const { checkAllUsersTokens } = require('../utils/access-check');
const db = require('../db');
const logger = require('../utils/logger');
async function updateRolesFromOldStructure() {
try {
logger.info('Starting migration of user roles from old structure');
// Получаем пользователей со старым полем role
const usersWithOldRoles = await db.query(`
SELECT id, role, address
FROM users
WHERE role IS NOT NULL AND role_id IS NULL
`);
logger.info(`Found ${usersWithOldRoles.rows.length} users with old role structure`);
for (const user of usersWithOldRoles.rows) {
// Определяем ID роли
let roleId = 2; // По умолчанию 'user'
if (user.role === 'ADMIN' || user.role === 'admin') {
roleId = 1; // 'admin'
}
// Обновляем пользователя
await db.query(
'UPDATE users SET role_id = $1 WHERE id = $2',
[roleId, user.id]
);
logger.info(`Updated user ${user.id} with role_id ${roleId} (from old role ${user.role})`);
}
// Запускаем проверку токенов для всех пользователей
await checkAllUsersTokens();
logger.info('Role migration completed successfully');
} catch (error) {
logger.error(`Error during role migration: ${error.message}`);
}
}
// Запуск скрипта
updateRolesFromOldStructure()
.then(() => {
logger.info('Migration script completed');
process.exit(0);
})
.catch(error => {
logger.error(`Unhandled error: ${error.message}`);
process.exit(1);
});