feat: add admin command to setup.sh

- ./setup.sh admin — create admin user directly in DB
- Hashes password via bcryptjs (already in dependencies)
- Creates both user and better-auth account records
- Shows existing admins, offers to promote existing users
- Validates email, password length (min 8)
- Added to interactive menu and CLI router

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-24 02:53:18 +03:00
parent 3b6c666744
commit bd195bd735

134
setup.sh
View File

@@ -208,6 +208,7 @@ print_usage() {
echo -e " ${CYAN}update${NC} Обновить проект (git pull + npm + prisma + rebuild)"
echo -e " ${CYAN}doctor${NC} Диагностика и автоисправление проблем"
echo -e " ${CYAN}status${NC} Статус всех сервисов"
echo -e " ${CYAN}admin${NC} Создать администратора"
echo -e " ${CYAN}logs${NC} [svc] Логи сервиса (по умолчанию: app)"
echo -e " ${CYAN}restart${NC} Перезапуск контейнеров"
echo -e " ${CYAN}reset${NC} Полный сброс (с подтверждением)"
@@ -767,6 +768,122 @@ cmd_update() {
echo ""
}
# ============================================================
# COMMAND: admin — создание админа
# ============================================================
cmd_admin() {
log_step "Создание администратора"
# Проверить что PostgreSQL доступен
if ! docker compose exec -T postgres pg_isready -U postgres &>/dev/null; then
log_err "PostgreSQL не запущен. Запусти: ./setup.sh doctor"
return 1
fi
# Проверить что таблица users существует
if ! docker compose exec -T postgres psql -U postgres -d liveserver -c "SELECT 1 FROM users LIMIT 0;" &>/dev/null; then
log_err "Таблица users не найдена. Запусти: npx prisma db push"
return 1
fi
# Показать существующих админов
local existing_admins
existing_admins=$(docker compose exec -T postgres psql -U postgres -d liveserver -t -c \
"SELECT email FROM users WHERE role = 'ADMIN';" 2>/dev/null | tr -d ' ' | grep -v '^$' || true)
if [[ -n "$existing_admins" ]]; then
echo ""
log_info "Существующие админы:"
echo "$existing_admins" | while read -r admin_email; do
echo -e " ${CYAN}${admin_email}${NC}"
done
echo ""
fi
# Спросить данные
local ADMIN_NAME ADMIN_EMAIL ADMIN_PASS
echo ""
ask "Имя администратора" "Admin" ADMIN_NAME
ask "Email" "" ADMIN_EMAIL
ask_secret "Пароль (мин. 8 символов)" "" ADMIN_PASS
# Валидация
if [[ -z "$ADMIN_EMAIL" ]]; then
log_err "Email обязателен"
return 1
fi
if [[ ${#ADMIN_PASS} -lt 8 ]]; then
log_err "Пароль должен быть минимум 8 символов"
return 1
fi
# Проверить что email не занят
local exists
exists=$(docker compose exec -T postgres psql -U postgres -d liveserver -t -c \
"SELECT count(*) FROM users WHERE email = '${ADMIN_EMAIL}';" 2>/dev/null | tr -d ' ')
if [[ "$exists" -gt 0 ]]; then
echo ""
if ask_yn "Пользователь ${ADMIN_EMAIL} уже существует. Сделать админом?" "y"; then
docker compose exec -T postgres psql -U postgres -d liveserver -c \
"UPDATE users SET role = 'ADMIN' WHERE email = '${ADMIN_EMAIL}';" &>/dev/null
log_ok "${ADMIN_EMAIL} теперь ADMIN"
return 0
else
log_info "Отменено"
return 0
fi
fi
# Хешировать пароль через node + bcryptjs (уже в зависимостях)
log_info "Хеширование пароля..."
local HASH
HASH=$(node -e "
const bcrypt = require('bcryptjs');
const hash = bcrypt.hashSync(process.argv[1], 10);
process.stdout.write(hash);
" "$ADMIN_PASS" 2>/dev/null)
if [[ -z "$HASH" ]]; then
log_err "Не удалось хешировать пароль (bcryptjs не установлен?)"
log_info "Попробуй: npm install && ./setup.sh admin"
return 1
fi
# Генерировать ID в стиле cuid
local USER_ID
USER_ID=$(node -e "process.stdout.write(require('crypto').randomBytes(12).toString('hex'))" 2>/dev/null || echo "admin_$(date +%s)")
# Создать пользователя
docker compose exec -T postgres psql -U postgres -d liveserver -c "
INSERT INTO users (id, email, name, \"emailVerified\", role, \"createdAt\", \"updatedAt\")
VALUES ('${USER_ID}', '${ADMIN_EMAIL}', '${ADMIN_NAME}', true, 'ADMIN', NOW(), NOW());
" &>/dev/null
# Создать аккаунт (better-auth accounts table для email+password)
local ACCOUNT_ID
ACCOUNT_ID=$(node -e "process.stdout.write(require('crypto').randomBytes(12).toString('hex'))" 2>/dev/null || echo "acc_$(date +%s)")
docker compose exec -T postgres psql -U postgres -d liveserver -c "
INSERT INTO accounts (id, \"userId\", \"accountId\", \"providerId\", \"password\", \"createdAt\", \"updatedAt\")
VALUES ('${ACCOUNT_ID}', '${USER_ID}', '${USER_ID}', 'credential', '${HASH}', NOW(), NOW());
" &>/dev/null
if [[ $? -eq 0 ]]; then
echo ""
log_ok "${GREEN}${BOLD}Администратор создан!${NC}"
echo -e " ${CYAN}Email:${NC} ${ADMIN_EMAIL}"
echo -e " ${CYAN}Пароль:${NC} (тот что ввёл)"
echo -e " ${CYAN}Роль:${NC} ADMIN"
echo ""
echo -e " Войди через: ${CYAN}http://localhost:3000/login${NC}"
else
log_err "Не удалось создать аккаунт"
fi
}
# ============================================================
# COMMAND: install (оригинальный setup)
# ============================================================
@@ -1168,6 +1285,9 @@ case "$CMD" in
doctor|fix)
cmd_doctor
;;
admin)
cmd_admin
;;
status|st)
cmd_status
;;
@@ -1199,9 +1319,10 @@ case "$CMD" in
echo -e " ${BOLD}1)${NC} ${CYAN}doctor${NC} — диагностика и исправление"
echo -e " ${BOLD}2)${NC} ${CYAN}update${NC} — обновить проект"
echo -e " ${BOLD}3)${NC} ${CYAN}status${NC} — статус сервисов"
echo -e " ${BOLD}4)${NC} ${CYAN}restart${NC}перезапуск контейнеров"
echo -e " ${BOLD}5)${NC} ${CYAN}install${NC} — полная переустановка"
echo -e " ${BOLD}6)${NC} ${CYAN}reset${NC} сброс всего"
echo -e " ${BOLD}4)${NC} ${CYAN}admin${NC} создать администратора"
echo -e " ${BOLD}5)${NC} ${CYAN}restart${NC} — перезапуск контейнеров"
echo -e " ${BOLD}6)${NC} ${CYAN}install${NC} — полная переустановка"
echo -e " ${BOLD}7)${NC} ${CYAN}reset${NC}сброс всего"
echo ""
ask "Выбери действие" "1" CHOICE
@@ -1209,9 +1330,10 @@ case "$CMD" in
1|doctor) cmd_doctor ;;
2|update) cmd_update ;;
3|status) cmd_status ;;
4|restart) cmd_restart ;;
5|install) cmd_install ;;
6|reset) cmd_reset ;;
4|admin) cmd_admin ;;
5|restart) cmd_restart ;;
6|install) cmd_install ;;
7|reset) cmd_reset ;;
*) log_err "Неизвестный выбор: ${CHOICE}"; print_usage ;;
esac
fi