#!/usr/bin/env bash set -euo pipefail REPO="ssomvk/sso-service" BRANCH="main" INSTALL_DIR="${INSTALL_DIR:-$HOME/sso-service}" RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m' info() { echo -e "${GREEN}✔${NC} $1"; } warn() { echo -e "${YELLOW}⚠${NC} $1"; } error() { echo -e "${RED}✘${NC} $1"; exit 1; } step() { echo -e "\n${CYAN}━━━ $1 ━━━${NC}"; } echo -e "${CYAN}" echo " ╔═══════════════════════════════════════╗" echo " ║ SSO Service Installer ║" echo " ╚═══════════════════════════════════════╝" echo -e "${NC}" # ─── Prerequisites ────────────────────────────────────────────── step "1/7 Checking prerequisites" command -v node >/dev/null 2>&1 || error "Node.js required → https://nodejs.org" command -v npm >/dev/null 2>&1 || error "npm required" command -v docker compose >/dev/null 2>&1 || error "Docker Compose required" info "node $(node -v), npm $(npm -v), docker compose found" # ─── Clone / Pull ─────────────────────────────────────────────── step "2/7 Downloading SSO Service" if [ -d "$INSTALL_DIR/.git" ]; then cd "$INSTALL_DIR" git pull --ff-only 2>/dev/null && info "Updated existing installation" || warn "Could not git pull, continuing" else mkdir -p "$INSTALL_DIR" if command -v git &>/dev/null; then git clone --depth 1 "https://github.com/$REPO.git" "$INSTALL_DIR" else curl -fsSL "https://github.com/$REPO/archive/refs/heads/$BRANCH.tar.gz" | tar xz --strip=1 -C "$INSTALL_DIR" fi info "Downloaded to $INSTALL_DIR" fi cd "$INSTALL_DIR" # ─── .env ──────────────────────────────────────────────────────── step "3/7 Configuring environment" if [ ! -f .env ]; then cp .env.example .env sed -i "s/change-me-access-secret-at-least-32-chars/$(openssl rand -hex 32)/" .env sed -i "s/change-me-refresh-secret-at-least-32-chars/$(openssl rand -hex 32)/" .env info "Created .env with random secrets" else info ".env already exists, keeping it" fi # shellcheck source=/dev/null set -a; source .env; set +a # ─── Docker ────────────────────────────────────────────────────── step "4/7 Starting infrastructure (PostgreSQL, Redis, RabbitMQ)" docker compose up -d 2>&1 info "Waiting for PostgreSQL..." for i in $(seq 1 30); do if docker compose exec -T postgres pg_isready -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" &>/dev/null; then info "PostgreSQL is ready" break fi [ "$i" -eq 30 ] && error "PostgreSQL did not start in time. Check: docker compose logs postgres" sleep 2 done # ─── Dependencies & Prisma ────────────────────────────────────── step "5/7 Installing dependencies and generating Prisma client" npm ci --no-audit --no-fund 2>&1 | tail -1 npx prisma generate 2>&1 | tail -1 export DATABASE_URL npx prisma db push --skip-generate 2>&1 info "Database schema applied" npx ts-node prisma/seed.ts 2>&1 info "Seed data created" # ─── Build ────────────────────────────────────────────────────── echo "" npm run build 2>&1 | tail -3 info "Application built" # ─── Start ────────────────────────────────────────────────────── step "6/7 Starting SSO Service" if command -v pm2 &>/dev/null; then pm2 delete sso-service 2>/dev/null || true pm2 start npm --name "sso-service" -- run start:prod pm2 save info "Started with PM2" else PORT="${PORT:-3000}" nohup node dist/main > sso.log 2>&1 & echo $! > .sso.pid info "Started in background (PID $(cat .sso.pid)), logs: sso.log" fi sleep 3 if curl -sfo /dev/null http://localhost:"${PORT:-3000}"/metrics 2>/dev/null; then info "Service is running on http://localhost:${PORT:-3000}" else warn "Service may still be starting... check sso.log" fi # ─── Done ──────────────────────────────────────────────────────── step "7/7 Installation complete!" echo "" echo -e " ${GREEN}Web panel:${NC} http://localhost:${PORT:-3000}" echo -e " ${GREEN}Admin login:${NC} admin@sso.local / admin123!" echo -e " ${GREEN}Metrics:${NC} http://localhost:${PORT:-3000}/metrics" echo -e " ${GREEN}RabbitMQ UI:${NC} http://localhost:15672 (sso / sso_secret)" echo "" echo -e " ${YELLOW}To stop:${NC} kill \$(cat $INSTALL_DIR/.sso.pid) (or pm2 stop sso-service)" echo -e " ${YELLOW}To update:${NC} cd $INSTALL_DIR && git pull && npm ci && npm run build && npm run start:prod" echo ""