Описание изменений

This commit is contained in:
2025-03-03 20:43:58 +03:00
parent 13e240f871
commit d36fc255d8
56 changed files with 4451 additions and 3390 deletions

View File

@@ -0,0 +1,22 @@
const fs = require('fs');
const path = require('path');
const packageJson = require('../package.json');
const dependencies = packageJson.dependencies || {};
const requiredDependencies = [
'express-rate-limit',
'winston',
'helmet',
'csurf'
];
const missingDependencies = requiredDependencies.filter(dep => !dependencies[dep]);
if (missingDependencies.length > 0) {
console.error('Missing dependencies:', missingDependencies);
console.error('Please install them with: yarn add ' + missingDependencies.join(' '));
process.exit(1);
}
console.log('All required dependencies are installed.');

View File

@@ -0,0 +1,43 @@
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);
// Проверяем все токены и их владельцев
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")) {
console.log(`Token ${i} error:`, error.message);
}
}
}
// Проверяем активные токены для всех известных адресов
const addresses = [
owner,
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
];
console.log("\nActive tokens:");
for (const address of addresses) {
const activeToken = await accessToken.activeTokens(address);
console.log(`${address}: Token ${activeToken.toString()}`);
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

View File

@@ -0,0 +1,51 @@
const hre = require("hardhat");
async function main() {
const accessToken = await hre.ethers.getContractAt(
"AccessToken",
"0xF352c498cF0857F472dC473E4Dd39551E79B1063"
);
const moderatorAddress = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8";
try {
console.log("\nMinting moderator token...");
const mintTx = await accessToken.mintAccessToken(moderatorAddress, 1); // MODERATOR
console.log("Waiting for transaction:", mintTx.hash);
await mintTx.wait();
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]}`);
} catch (error) {
console.log("Moderator token minting error:", error.message);
}
// Проверяем все активные токены
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]}`);
} catch (error) {
console.log(`${address}: ${error.message}`);
}
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error("Script error:", error);
process.exit(1);
});

View File

@@ -0,0 +1,23 @@
const hre = require("hardhat");
async function main() {
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);
// Создаем первый админский токен для владельца контракта
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);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

View File

@@ -0,0 +1,62 @@
const { Pool } = require('pg');
const dotenv = require('dotenv');
dotenv.config();
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
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)
VALUES (
'Тестовая доска',
'Описание тестовой доски',
(SELECT id FROM users WHERE address = '0xf45aa4917b3775ba37f48aeb3dc1a943561e9e0b'),
TRUE
)
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(`
INSERT INTO kanban_columns (board_id, title, position)
VALUES
($1, 'Backlog', 0),
($1, 'In Progress', 1),
($1, 'Review', 2),
($1, 'Done', 3)
ON CONFLICT DO NOTHING
`, [boardId]);
}
console.log('База данных инициализирована успешно');
} catch (error) {
console.error('Ошибка при инициализации базы данных:', error);
} finally {
await pool.end();
}
}
initDb();

View File

@@ -0,0 +1,58 @@
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 tx = await accessToken.mintAccessToken(owner, 0); // 0 = ADMIN
await tx.wait();
console.log(`Admin token minted for ${owner}`);
const role = await accessToken.checkRole(owner);
console.log("Owner role:", ["ADMIN", "MODERATOR", "SUPPORT"][role]);
} catch (error) {
console.log("Admin token minting error:", error.message);
}
// Создаем тестовый токен модератора
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]);
} catch (error) {
console.log("Moderator token minting error:", error.message);
}
// Проверяем все токены
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]}`);
} catch (error) {
// Пропускаем несуществующие токены
if (!error.message.includes("nonexistent token")) {
console.log(`Token ${i} error:`, error.message);
}
}
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

View File

@@ -0,0 +1,72 @@
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

@@ -0,0 +1,26 @@
const hre = require("hardhat");
async function main() {
const accessToken = await hre.ethers.getContractAt(
"AccessToken",
"0xF352c498cF0857F472dC473E4Dd39551E79B1063"
);
// Отзываем все токены от 1 до 3
for (let i = 1; i <= 3; i++) {
try {
const tx = await accessToken.revokeToken(i);
await tx.wait();
console.log(`Token ${i} revoked`);
} catch (error) {
console.log(`Token ${i} revoke error:`, error.message);
}
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

View File

@@ -0,0 +1,68 @@
const { Pool } = require('pg');
const fs = require('fs');
const path = require('path');
require('dotenv').config();
// Подключение к БД
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false
});
async function runMigrations() {
try {
console.log('Запуск миграций...');
// Создаем таблицу для отслеживания миграций, если её нет
await pool.query(`
CREATE TABLE IF NOT EXISTS migrations (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
applied_at TIMESTAMP DEFAULT NOW()
)
`);
// Получаем список уже примененных миграций
const { rows } = await pool.query('SELECT name FROM migrations');
const appliedMigrations = rows.map(row => row.name);
// Получаем список файлов миграций
const migrationsDir = path.join(__dirname, '../migrations');
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]
);
console.log(`Миграция ${file} успешно применена`);
} else {
console.log(`Миграция ${file} уже применена`);
}
}
console.log('Все миграции успешно применены');
} catch (error) {
console.error('Ошибка при выполнении миграций:', error);
process.exit(1);
} finally {
await pool.end();
}
}
runMigrations();