From e59ba0ab979b957dee381714d0a427cabcbf2540 Mon Sep 17 00:00:00 2001 From: joylessorchid Date: Tue, 24 Mar 2026 03:47:11 +0300 Subject: [PATCH] feat: create first admin during ./setup.sh install Step 6/7 asks for admin name/email/password and creates the user directly in the database. Can be skipped (creates later via ./setup.sh admin). Also fixed PgBouncer wait_for_service to use nc instead of pg_isready. --- setup.sh | 67 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/setup.sh b/setup.sh index f03df6c..25a7f24 100644 --- a/setup.sh +++ b/setup.sh @@ -891,7 +891,7 @@ cmd_admin() { cmd_install() { # --- Step 1: Check & install dependencies --- - log_step "Шаг 1/6 — Проверка и установка зависимостей" + log_step "Шаг 1/7 — Проверка и установка зависимостей" local MISSING=0 install_if_missing docker "https://docs.docker.com/get-docker/" || MISSING=1 @@ -912,7 +912,7 @@ cmd_install() { log_ok "Node.js: $NODE_VER" # --- Step 2: Choose mode --- - log_step "Шаг 2/6 — Режим запуска" + log_step "Шаг 2/7 — Режим запуска" echo "" echo -e " ${BOLD}1)${NC} Локальная разработка (localhost, без SSL)" @@ -947,7 +947,7 @@ cmd_install() { fi # --- Step 3: Configure environment --- - log_step "Шаг 3/6 — Настройка окружения" + log_step "Шаг 3/7 — Настройка окружения" local PG_PASSWORD MINIO_USER MINIO_PASS AUTH_SECRET DEV_ACCESS_KEY S3_BUCKET PG_PASSWORD=$(generate_password) @@ -1011,7 +1011,7 @@ cmd_install() { fi # --- Step 4: Generate .env --- - log_step "Шаг 4/6 — Генерация .env" + log_step "Шаг 4/7 — Генерация .env" local APP_URL S3_ENDPOINT if [[ "$MODE" == "2" ]]; then @@ -1075,7 +1075,7 @@ ENVEOF log_ok ".env создан" # --- Step 5: Install & setup --- - log_step "Шаг 5/6 — Установка и настройка" + log_step "Шаг 5/7 — Установка и настройка" if [[ ! -d "node_modules" ]]; then echo -e " Установка npm зависимостей..." @@ -1103,7 +1103,7 @@ ENVEOF wait_for_service "PostgreSQL" "docker compose exec -T postgres pg_isready -U postgres" 30 || exit 1 wait_for_service "Redis" "docker compose exec -T redis redis-cli ping 2>/dev/null | grep -q PONG" 15 || exit 1 - wait_for_service "PgBouncer" "docker compose exec -T pgbouncer pg_isready -h 127.0.0.1 -p 6432" 15 || \ + wait_for_service "PgBouncer" "docker compose exec -T pgbouncer sh -c 'echo | nc -w 2 127.0.0.1 6432'" 15 || \ log_warn "PgBouncer не отвечает — продолжаем без него" echo -e " Применение миграций..." @@ -1126,8 +1126,59 @@ ENVEOF fi fi - # --- Step 6: Done --- - log_step "Шаг 6/6 — Готово!" + # --- Step 6: First admin --- + log_step "Шаг 6/7 — Первый администратор" + + echo "" + echo -e " ${BOLD}Создай аккаунт администратора для входа в систему.${NC}" + echo "" + + local ADMIN_NAME ADMIN_EMAIL ADMIN_PASS + ask "Имя администратора" "Admin" ADMIN_NAME + ask "Email" "" ADMIN_EMAIL + ask_secret "Пароль (мин. 8 символов)" "" ADMIN_PASS + + if [[ -n "$ADMIN_EMAIL" && ${#ADMIN_PASS} -ge 8 ]]; then + 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 [[ -n "$HASH" ]]; then + local USER_ID ACCOUNT_ID + USER_ID=$(node -e "process.stdout.write(require('crypto').randomBytes(12).toString('hex'))" 2>/dev/null) + ACCOUNT_ID=$(node -e "process.stdout.write(require('crypto').randomBytes(12).toString('hex'))" 2>/dev/null) + + 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 + + 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 + log_ok "Администратор создан: ${ADMIN_EMAIL}" + else + log_warn "Не удалось создать админа — создай позже: ./setup.sh admin" + fi + else + log_warn "bcryptjs не готов — создай админа позже: ./setup.sh admin" + fi + else + if [[ -z "$ADMIN_EMAIL" ]]; then + log_info "Пропущено — создай позже: ./setup.sh admin" + else + log_err "Пароль должен быть мин. 8 символов — создай позже: ./setup.sh admin" + fi + fi + + # --- Step 7: Done --- + log_step "Шаг 7/7 — Готово!" echo "" if [[ "$MODE" == "2" ]]; then