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:
134
setup.sh
134
setup.sh
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user