Files
kspguti-schedule/scripts/reset-admin-password.js
kilyabin 3f74709513 feat: добавлен режим "Каникулы" и улучшения админ-панели
- Добавлен режим "Каникулы" который полностью заменяет главную страницу:
  * Карточка с эмодзи 🎉 и праздничным сообщением
  * Поддержка произвольного текста в формате Markdown
  * Карточка центрируется по вертикали при отсутствии текста

- Улучшения админ-панели:
  * Переключатель режима "Каникулы"
  * Редактор текста с подсказками по форматированию Markdown
  * Исправлена проблема с обновлением настроек (сохранение существующих значений)
  * Исправлена проблема с debug опциями в production (не блокируют обновление обычных настроек)

- Оптимизация загрузки:
  * Проверка режима каникул перед загрузкой групп
  * Динамическая загрузка ReactMarkdown только при необходимости
  * Кеш настроек сбрасывается на главной странице для актуальности

- Добавлен скрипт для сброса пароля администратора (scripts/reset-admin-password.js)

- Установлена библиотека react-markdown для рендеринга Markdown контента
2025-12-04 23:22:42 +04:00

122 lines
3.9 KiB
JavaScript
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* Скрипт для сброса пароля администратора
*
* Использование:
* node scripts/reset-admin-password.js [новый_пароль]
* или
* node scripts/reset-admin-password.js (интерактивный режим)
*/
const Database = require('better-sqlite3');
const bcrypt = require('bcrypt');
const path = require('path');
const fs = require('fs');
const readline = require('readline');
// Определяем путь к базе данных
function findDatabase() {
const possiblePaths = [
path.join(process.cwd(), 'data', 'schedule-app.db'),
path.join(process.cwd(), '.next', 'standalone', 'data', 'schedule-app.db'),
'/opt/kspguti-schedule/data/schedule-app.db',
'/opt/kspguti-schedule/.next/standalone/data/schedule-app.db',
];
for (const dbPath of possiblePaths) {
if (fs.existsSync(dbPath)) {
return dbPath;
}
}
return null;
}
// Функция для чтения пароля из терминала (простая версия)
function readPassword(prompt) {
return new Promise((resolve) => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question(prompt, (password) => {
rl.close();
resolve(password);
});
});
}
async function main() {
console.log('🔐 Сброс пароля администратора\n');
// Находим базу данных
const dbPath = findDatabase();
if (!dbPath) {
console.error('❌ Ошибка: База данных не найдена!');
console.log('\nИскали в следующих местах:');
console.log(' - ' + path.join(process.cwd(), 'data', 'schedule-app.db'));
console.log(' - ' + path.join(process.cwd(), '.next', 'standalone', 'data', 'schedule-app.db'));
console.log(' - /opt/kspguti-schedule/data/schedule-app.db');
console.log(' - /opt/kspguti-schedule/.next/standalone/data/schedule-app.db');
process.exit(1);
}
console.log('✓ Найдена база данных: ' + dbPath + '\n');
// Получаем новый пароль
let newPassword;
if (process.argv[2]) {
newPassword = process.argv[2];
} else {
newPassword = await readPassword('Введите новый пароль (минимум 8 символов): ');
if (newPassword.length < 8) {
console.error('❌ Ошибка: Пароль должен содержать минимум 8 символов');
process.exit(1);
}
const confirmPassword = await readPassword('Подтвердите пароль: ');
if (newPassword !== confirmPassword) {
console.error('❌ Ошибка: Пароли не совпадают');
process.exit(1);
}
}
if (newPassword.length < 8) {
console.error('❌ Ошибка: Пароль должен содержать минимум 8 символов');
process.exit(1);
}
// Открываем базу данных и обновляем пароль
try {
console.log('\n⏳ Обновление пароля...');
const db = new Database(dbPath);
// Хешируем новый пароль
const saltRounds = 10;
const hash = bcrypt.hashSync(newPassword, saltRounds);
// Обновляем пароль в базе данных
db.prepare('INSERT OR REPLACE INTO admin_password (id, password_hash) VALUES (1, ?)').run(hash);
db.close();
console.log('✅ Пароль успешно изменен!');
console.log('\n⚠ ВАЖНО: Сохраните пароль в безопасном месте!');
if (process.argv[2]) {
console.log('Новый пароль: ' + newPassword);
}
} catch (error) {
console.error('❌ Ошибка при изменении пароля:');
console.error(error.message);
process.exit(1);
}
}
main();