Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# CSF Profile Assessment Tool — Guided Installer (Windows PowerShell)
# Usage: .\install.ps1
# If blocked by execution policy, run first:
# Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
#
# This file is intentionally readable. Review before running.

$ErrorActionPreference = "Stop"
$InstallerPort = 31338
$RepoUrl = "https://github.com/CPAtoCybersecurity/csf_profile.git"
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path

function Write-Info { Write-Host "▶ $args" -ForegroundColor Cyan }
function Write-Success { Write-Host "✔ $args" -ForegroundColor Green }
function Write-Warn { Write-Host "⚠ $args" -ForegroundColor Yellow }
function Write-Err { Write-Host "✖ $args" -ForegroundColor Red }

# ── 1. Check Git ──────────────────────────────────────────────────────────────
Write-Info "Checking prerequisites…"
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
Write-Err "Git is not installed. Download from https://git-scm.com and re-run."
exit 1
}
Write-Success "Git found: $(git --version)"

# ── 2. Check Node 18+ ─────────────────────────────────────────────────────────
if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
Write-Err "Node.js is not installed. Install Node 18 LTS from https://nodejs.org and re-run."
exit 1
}

$NodeMajor = [int](node -e "process.stdout.write(String(process.versions.node.split('.')[0]))")
if ($NodeMajor -lt 18) {
Write-Err "Node.js $NodeMajor found, but 18+ is required. Upgrade at https://nodejs.org"
exit 1
}
Write-Success "Node.js $(node --version)"

# ── 3. Clone or use existing repo ─────────────────────────────────────────────
if (Test-Path (Join-Path $ScriptDir "package.json")) {
$RepoDir = $ScriptDir
Write-Info "Using existing repo at: $RepoDir"
} else {
$RepoDir = Join-Path $HOME "csf_profile"
if (-not (Test-Path (Join-Path $RepoDir ".git"))) {
Write-Info "Cloning CSF Profile repository…"
git clone $RepoUrl $RepoDir
} else {
Write-Info "Repo already cloned at $RepoDir"
}
}

Set-Location $RepoDir

# ── 4. Install npm dependencies ───────────────────────────────────────────────
Write-Info "Installing dependencies (npm install)…"
npm install --silent
Write-Success "Dependencies installed."

# ── 5. Check port availability ────────────────────────────────────────────────
$portInUse = netstat -an | Select-String ":$InstallerPort\s+LISTENING"
if ($portInUse) {
Write-Warn "Port $InstallerPort is already in use. The installer may already be running."
Write-Warn "Open http://localhost:$InstallerPort in your browser, or kill the process and retry."
exit 0
}

# ── 6. Start installer server ─────────────────────────────────────────────────
Write-Info "Starting installer server on port $InstallerPort…"
$serverScript = Join-Path $RepoDir "installer\server.js"
$serverProcess = Start-Process -FilePath "node" -ArgumentList "`"$serverScript`" `"$RepoDir`"" `
-PassThru -WindowStyle Hidden
Start-Sleep -Seconds 1

if ($serverProcess.HasExited) {
Write-Err "Installer server failed to start. Check installer\server.js exists."
exit 1
}
Write-Success "Installer server running (PID $($serverProcess.Id))."

# ── 7. Open browser ──────────────────────────────────────────────────────────
$WizardUrl = "http://localhost:$InstallerPort"
Write-Info "Opening wizard at $WizardUrl"
Start-Process $WizardUrl

Write-Host ""
Write-Host "CSF Profile Installer is running." -ForegroundColor Green -NoNewline
Write-Host ""
Write-Host " Wizard: $WizardUrl" -ForegroundColor Cyan
Write-Host " The installer will guide you through the remaining setup steps."
Write-Host " Close this window or press Ctrl+C to stop the installer server."
Write-Host ""

$serverProcess.WaitForExit()
102 changes: 102 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env bash
# CSF Profile Assessment Tool — Guided Installer
# Usage: bash install.sh (or: curl -sSL <url>/install.sh | bash)
# This file is intentionally readable. Inspect it before piping to bash.

set -euo pipefail

INSTALLER_PORT=31338
REPO_URL="https://github.com/CPAtoCybersecurity/csf_profile.git"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"

# ── Colours ────────────────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'
BOLD='\033[1m'; RESET='\033[0m'

info() { echo -e "${CYAN}▶${RESET} $*"; }
success() { echo -e "${GREEN}✔${RESET} $*"; }
warn() { echo -e "${YELLOW}⚠${RESET} $*"; }
error() { echo -e "${RED}✖${RESET} $*" >&2; }
die() { error "$*"; exit 1; }

# ── 1. Check Git ───────────────────────────────────────────────────────────────
info "Checking prerequisites..."

if ! command -v git &>/dev/null; then
die "Git is not installed. Install it from https://git-scm.com and re-run this script."
fi
success "Git found: $(git --version)"

# ── 2. Check Node 18+ ─────────────────────────────────────────────────────────
if ! command -v node &>/dev/null; then
die "Node.js is not installed. Install Node 18 LTS from https://nodejs.org and re-run."
fi

NODE_VERSION=$(node -e "process.stdout.write(String(process.versions.node.split('.')[0]))")
if [ "$NODE_VERSION" -lt 18 ]; then
die "Node.js ${NODE_VERSION} found, but 18+ is required. Upgrade at https://nodejs.org"
fi
success "Node.js v$(node --version | sed 's/v//')"

# ── 3. Clone or use existing repo ─────────────────────────────────────────────
if [ -f "$SCRIPT_DIR/package.json" ]; then
REPO_DIR="$SCRIPT_DIR"
info "Using existing repo at: $REPO_DIR"
else
REPO_DIR="${HOME}/csf_profile"
if [ ! -d "$REPO_DIR/.git" ]; then
info "Cloning CSF Profile repository..."
git clone "$REPO_URL" "$REPO_DIR"
else
info "Repo already cloned at $REPO_DIR"
fi
fi

cd "$REPO_DIR"

# ── 4. Install npm dependencies ───────────────────────────────────────────────
info "Installing dependencies (npm install)..."
npm install --silent
success "Dependencies installed."

# ── 5. Check port availability ────────────────────────────────────────────────
if lsof -iTCP:"$INSTALLER_PORT" -sTCP:LISTEN &>/dev/null 2>&1; then
warn "Port $INSTALLER_PORT is already in use. The installer may already be running."
warn "Open http://localhost:$INSTALLER_PORT in your browser, or kill the process and retry."
exit 0
fi

# ── 6. Start installer server ─────────────────────────────────────────────────
info "Starting installer server on port $INSTALLER_PORT..."
node "$REPO_DIR/installer/server.js" "$REPO_DIR" &
SERVER_PID=$!
sleep 1 # Brief pause to let the server bind

if ! kill -0 "$SERVER_PID" 2>/dev/null; then
die "Installer server failed to start. Check installer/server.js exists."
fi
success "Installer server running (PID $SERVER_PID)."

# ── 7. Open browser ──────────────────────────────────────────────────────────
WIZARD_URL="http://localhost:$INSTALLER_PORT"
info "Opening wizard at $WIZARD_URL"

if command -v open &>/dev/null; then
open "$WIZARD_URL" # macOS
elif command -v xdg-open &>/dev/null; then
xdg-open "$WIZARD_URL" # Linux
elif command -v wslview &>/dev/null; then
wslview "$WIZARD_URL" # WSL
else
warn "Could not auto-open browser. Please navigate to: $WIZARD_URL"
fi

echo ""
echo -e "${BOLD}${GREEN}CSF Profile Installer is running.${RESET}"
echo -e " Wizard: ${CYAN}$WIZARD_URL${RESET}"
echo -e " The installer will guide you through the remaining setup steps."
echo -e " Press Ctrl+C here to stop the installer server if needed."
echo ""

# Keep script alive until server exits
wait "$SERVER_PID" 2>/dev/null || true
Loading
Loading