diff --git a/ct/nexus-db.sh b/ct/nexus-db.sh index cdf92ff..61b2488 100755 --- a/ct/nexus-db.sh +++ b/ct/nexus-db.sh @@ -28,6 +28,8 @@ DEFAULT_DB_NAME="nexus" DEFAULT_DB_USER="nexus" DEFAULT_DB_PORT="5432" +source <(curl -fsSL "$LIB_URL/build.func") + # ── app-specific prompts (host TTY; each skipped if the var is preset) ─────── prompt_app_config() { echo diff --git a/install/nexus-db-install.sh b/install/nexus-db-install.sh index b4f9c78..20af92d 100755 --- a/install/nexus-db-install.sh +++ b/install/nexus-db-install.sh @@ -24,6 +24,13 @@ DB_NAME="${DB_NAME:-nexus}" DB_USER="${DB_USER:-nexus}" DB_PORT="${DB_PORT:-5432}" +# Values land verbatim in SQL and pg_hba.conf — accept only safe shapes. +[[ "$DB_NAME" =~ ^[a-z_][a-z0-9_]*$ ]] || { msg_err "DB_NAME must be a plain lowercase identifier: $DB_NAME"; exit 1; } +[[ "$DB_USER" =~ ^[a-z_][a-z0-9_]*$ ]] || { msg_err "DB_USER must be a plain lowercase identifier: $DB_USER"; exit 1; } +[[ "$DB_PORT" =~ ^[0-9]{2,5}$ ]] || { msg_err "DB_PORT must be numeric: $DB_PORT"; exit 1; } +[[ "$NEXUS_APP_IP" =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ || "$NEXUS_APP_IP" =~ ^[0-9a-fA-F:]+$ ]] \ + || { msg_err "NEXUS_APP_IP must be a single host IP: $NEXUS_APP_IP"; exit 1; } + PG_MAJOR=16 CRED_FILE="/root/nexus-db.credentials" @@ -92,6 +99,14 @@ if [[ "$(run_psql -c "SELECT 1 FROM pg_roles WHERE rolname='$DB_USER'")" != "1" DB_PASS="$(openssl rand -base64 32 | tr -d '/+=' | head -c 32)" run_psql -c "CREATE ROLE $DB_USER LOGIN PASSWORD '$DB_PASS' NOSUPERUSER NOCREATEDB NOCREATEROLE" msg_ok "Role $DB_USER created (least privilege)" +elif [[ ! -f "$CRED_FILE" ]]; then + # Recovery: role exists but the generated password was never persisted + # (first run died between CREATE ROLE and credentials write). Rotate so + # the credentials file is authoritative again. + msg_warn "Role $DB_USER exists but $CRED_FILE is missing — rotating password" + DB_PASS="$(openssl rand -base64 32 | tr -d '/+=' | head -c 32)" + run_psql -c "ALTER ROLE $DB_USER PASSWORD '$DB_PASS'" + msg_ok "Password rotated" else DB_PASS="" msg_warn "Role $DB_USER already exists, password unchanged"