diff --git a/frontend-modern/public/debug.html b/frontend-modern/public/debug.html
deleted file mode 100644
index a67a15f97..000000000
--- a/frontend-modern/public/debug.html
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
- Debug Pulse
-
-
- Debug Page
- Initial content - if you see this, JavaScript didn't run
-
-
-
Log:
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend-modern/public/test.html b/frontend-modern/public/test.html
deleted file mode 100644
index b2bdf5487..000000000
--- a/frontend-modern/public/test.html
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
- Test App Loading
-
-
- Testing App Loading
-
-
-
-
\ No newline at end of file
diff --git a/scripts/test-all.sh b/scripts/test-all.sh
deleted file mode 100755
index 9e6c967d1..000000000
--- a/scripts/test-all.sh
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/bin/bash
-
-# Master test script that runs all test suites
-# Run this before any release!
-
-set -e
-
-VERSION=${1:-$(cat VERSION)}
-API_TOKEN=${2:-""}
-PULSE_URL=${3:-"http://localhost:7655"}
-
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[1;33m'
-BLUE='\033[0;34m'
-NC='\033[0m'
-
-echo "================================================"
-echo -e "${BLUE}PULSE COMPREHENSIVE TEST SUITE v${VERSION}${NC}"
-echo "================================================"
-echo ""
-
-TOTAL_PASSED=0
-TOTAL_FAILED=0
-FAILED_SUITES=()
-
-run_test_suite() {
- local suite_name="$1"
- local script_path="$2"
- shift 2
- local args="$@"
-
- echo -e "${YELLOW}Running: $suite_name${NC}"
- echo "----------------------------------------"
-
- if [ -f "$script_path" ]; then
- if timeout 60 $script_path $args 2>&1 | tee /tmp/test_output.txt | grep -E "✓|✗|passed|failed|PASS|FAIL"; then
- # Extract pass/fail counts if possible
- if grep -q "All tests passed" /tmp/test_output.txt; then
- echo -e "${GREEN}✅ $suite_name: PASSED${NC}"
- ((TOTAL_PASSED++))
- elif grep -q "FAILED\|Failed" /tmp/test_output.txt; then
- echo -e "${RED}❌ $suite_name: FAILED${NC}"
- ((TOTAL_FAILED++))
- FAILED_SUITES+=("$suite_name")
- else
- echo -e "${YELLOW}⚠️ $suite_name: COMPLETED (check output)${NC}"
- fi
- else
- echo -e "${RED}❌ $suite_name: ERROR or TIMEOUT${NC}"
- ((TOTAL_FAILED++))
- FAILED_SUITES+=("$suite_name")
- fi
- else
- echo -e "${YELLOW}⚠️ $suite_name: Script not found${NC}"
- fi
- echo ""
-}
-
-# Change to Pulse directory
-cd /opt/pulse
-
-echo -e "${BLUE}Starting comprehensive test suite...${NC}"
-echo ""
-
-# 1. Main release tests
-if [ -n "$API_TOKEN" ]; then
- export API_TOKEN
-fi
-run_test_suite "Release Tests" "./scripts/test-release.sh"
-
-# 2. Edge case tests
-run_test_suite "Edge Case Tests" "./scripts/test-edge-cases.sh" "$PULSE_URL"
-
-# 3. Proxy scenario tests
-run_test_suite "Proxy Scenarios" "./scripts/test-proxy-scenarios.sh" "$PULSE_URL" "$API_TOKEN"
-
-# 4. Security tests
-run_test_suite "Security Tests" "./scripts/test-security.sh" "$PULSE_URL" "$API_TOKEN"
-
-# 5. Installation method tests (non-destructive)
-run_test_suite "Installation Tests" "./scripts/test-installation-methods.sh" "$VERSION"
-
-echo "================================================"
-echo -e "${BLUE}TEST SUITE SUMMARY${NC}"
-echo "================================================"
-echo ""
-echo -e "Test Suites Passed: ${GREEN}$TOTAL_PASSED${NC}"
-echo -e "Test Suites Failed: ${RED}$TOTAL_FAILED${NC}"
-
-if [ ${#FAILED_SUITES[@]} -gt 0 ]; then
- echo ""
- echo -e "${RED}Failed test suites:${NC}"
- for suite in "${FAILED_SUITES[@]}"; do
- echo " - $suite"
- done
- echo ""
- echo -e "${RED}⚠️ DO NOT RELEASE - Tests failed!${NC}"
- echo ""
- echo "Run individual test suites for details:"
- echo " ./scripts/test-release.sh"
- echo " ./scripts/test-edge-cases.sh"
- echo " ./scripts/test-proxy-scenarios.sh"
- echo " ./scripts/test-security.sh"
- echo " ./scripts/test-installation-methods.sh"
- exit 1
-else
- echo ""
- echo -e "${GREEN}✅ ALL TEST SUITES PASSED!${NC}"
- echo -e "${GREEN}Safe to proceed with release v${VERSION}${NC}"
-fi
-
-echo ""
-echo "Additional manual testing recommended:"
-echo " 1. Test actual ProxmoxVE LXC installation"
-echo " 2. Test Docker deployment on different architectures"
-echo " 3. Test behind real nginx/Cloudflare"
-echo " 4. Test upgrade from previous version"
-echo " 5. Load test with many concurrent users"
\ No newline at end of file
diff --git a/scripts/test-edge-cases.sh b/scripts/test-edge-cases.sh
deleted file mode 100755
index 8830dbae8..000000000
--- a/scripts/test-edge-cases.sh
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/bin/bash
-
-# Edge case testing for Pulse
-# Tests the weird stuff that breaks in production
-
-set -e
-
-PULSE_URL=${1:-http://localhost:7655}
-
-echo "================================================"
-echo "EDGE CASE TESTING"
-echo "================================================"
-
-echo ""
-echo "Testing URL variations that break reverse proxies..."
-echo "----------------------------------------------------"
-
-# Test all the ways users might access Pulse
-URLS=(
- "$PULSE_URL" # No trailing slash
- "$PULSE_URL/" # With trailing slash
- "$PULSE_URL//" # Double slash (happens with bad proxy configs)
- "$PULSE_URL/./" # Relative path (should not happen!)
- "$PULSE_URL/index.html" # Direct file access
-)
-
-for url in "${URLS[@]}"; do
- echo -n "Testing: $url ... "
- STATUS=$(curl -s -o /dev/null -w "%{http_code}" -I "$url" 2>/dev/null || echo "FAIL")
- LOCATION=$(curl -s -I "$url" 2>/dev/null | grep -i "^location:" | cut -d' ' -f2 | tr -d '\r\n' || echo "none")
-
- if [[ "$STATUS" == "200" ]]; then
- echo "✓ 200 OK"
- elif [[ "$STATUS" == "301" ]] || [[ "$STATUS" == "302" ]]; then
- echo "⚠️ Redirect to: $LOCATION"
- if [[ "$LOCATION" == "./" ]] || [[ "$LOCATION" == "../" ]]; then
- echo " ❌ RELATIVE REDIRECT DETECTED - THIS BREAKS PROXIES!"
- fi
- else
- echo "❌ Status: $STATUS"
- fi
-done
-
-echo ""
-echo "Testing problematic header combinations..."
-echo "----------------------------------------------------"
-
-# Headers that various proxies send
-HEADER_TESTS=(
- "-H 'Host: example.com'" # Different host
- "-H 'X-Forwarded-Host: proxy.local' -H 'X-Forwarded-Proto: https'" # Proxy headers
- "-H 'X-Real-IP: 10.0.0.1' -H 'X-Forwarded-For: 10.0.0.1'" # Multiple IPs
- "-H 'CF-Connecting-IP: 1.2.3.4'" # Cloudflare
- "-H 'X-Forwarded-Prefix: /pulse'" # Subpath proxy
-)
-
-for headers in "${HEADER_TESTS[@]}"; do
- echo -n "Testing with: $headers ... "
- if eval "curl -s $headers '$PULSE_URL' | grep -q 'Pulse'" 2>/dev/null; then
- echo "✓"
- else
- echo "❌ Failed"
- fi
-done
-
-echo ""
-echo "Testing authentication edge cases..."
-echo "----------------------------------------------------"
-
-# Test various auth header formats
-echo -n "Empty API token header: "
-curl -s -H "X-API-Token: " "$PULSE_URL/api/health" | grep -q "healthy" && echo "✓" || echo "❌"
-
-echo -n "Malformed API token: "
-RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -H "X-API-Token: notavalidtoken" "$PULSE_URL/api/state")
-[[ "$RESPONSE" == "401" ]] && echo "✓ Properly rejected" || echo "❌ Status: $RESPONSE"
-
-echo -n "SQL injection in API token: "
-RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -H "X-API-Token: ' OR '1'='1" "$PULSE_URL/api/state")
-[[ "$RESPONSE" == "401" ]] && echo "✓ Properly rejected" || echo "❌ Status: $RESPONSE"
-
-echo ""
-echo "Testing concurrent connections..."
-echo "----------------------------------------------------"
-
-echo "Sending 50 concurrent requests..."
-for i in {1..50}; do
- curl -s "$PULSE_URL/api/health" > /dev/null &
-done
-wait
-echo "✓ Handled concurrent load"
-
-echo ""
-echo "Testing large request handling..."
-echo "----------------------------------------------------"
-
-# Test with large headers
-echo -n "Large header (10KB): "
-LARGE_HEADER=$(head -c 10000 /dev/zero | tr '\0' 'A')
-RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -H "X-Large: $LARGE_HEADER" "$PULSE_URL/api/health" 2>/dev/null || echo "FAIL")
-[[ "$RESPONSE" == "200" ]] && echo "✓" || echo "❌ Status: $RESPONSE"
-
-echo ""
-echo "Testing special characters in URLs..."
-echo "----------------------------------------------------"
-
-SPECIAL_PATHS=(
- "/api/health?test=" # XSS attempt
- "/api/health?test=';DROP TABLE--" # SQL injection
- "/api/../../../etc/passwd" # Path traversal
- "/api/health%00.json" # Null byte
- "/api/health?test=%" # Invalid encoding
-)
-
-for path in "${SPECIAL_PATHS[@]}"; do
- echo -n "Testing: $path ... "
- RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" "$PULSE_URL$path" 2>/dev/null || echo "FAIL")
- if [[ "$RESPONSE" == "200" ]] || [[ "$RESPONSE" == "400" ]] || [[ "$RESPONSE" == "404" ]]; then
- echo "✓ Handled safely ($RESPONSE)"
- else
- echo "❌ Unexpected: $RESPONSE"
- fi
-done
-
-echo ""
-echo "Testing WebSocket edge cases..."
-echo "----------------------------------------------------"
-
-echo -n "WebSocket with wrong protocol: "
-curl -s -I -H "Upgrade: wrong" "$PULSE_URL/ws" | grep -q "HTTP/1.1" && echo "✓" || echo "❌"
-
-echo -n "WebSocket with auth token: "
-curl -s -I -H "Upgrade: websocket" -H "X-API-Token: test" "$PULSE_URL/ws" | grep -q "HTTP/1.1" && echo "✓" || echo "❌"
-
-echo ""
-echo "================================================"
-echo "EDGE CASE TESTING COMPLETE"
-echo "================================================"
\ No newline at end of file
diff --git a/scripts/test-installation-methods.sh b/scripts/test-installation-methods.sh
deleted file mode 100755
index dfe43fd53..000000000
--- a/scripts/test-installation-methods.sh
+++ /dev/null
@@ -1,200 +0,0 @@
-#!/bin/bash
-
-# Test different installation methods
-# Catches issues with install script, Docker, systemd, etc.
-
-set -e
-
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[1;33m'
-NC='\033[0m'
-
-echo "================================================"
-echo "INSTALLATION METHOD TESTING"
-echo "================================================"
-
-VERSION=${1:-$(cat VERSION)}
-
-echo ""
-echo "1. INSTALL SCRIPT VALIDATION"
-echo "============================"
-
-echo -n "Install script exists on GitHub: "
-if curl -s -f https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh > /dev/null; then
- echo -e "${GREEN}✓${NC}"
-else
- echo -e "${RED}✗${NC}"
-fi
-
-echo -n "Install script is executable: "
-SCRIPT=$(curl -s https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh)
-if echo "$SCRIPT" | head -1 | grep -q "^#!/bin/bash"; then
- echo -e "${GREEN}✓${NC}"
-else
- echo -e "${RED}✗${NC}"
-fi
-
-echo -n "Install script has version detection: "
-if echo "$SCRIPT" | grep -q "VERSION="; then
- echo -e "${GREEN}✓${NC}"
-else
- echo -e "${RED}✗${NC}"
-fi
-
-echo ""
-echo "2. GITHUB RELEASE ARTIFACTS"
-echo "==========================="
-
-ARTIFACTS=(
- "pulse-v${VERSION}-linux-amd64.tar.gz"
- "pulse-v${VERSION}-linux-arm64.tar.gz"
- "pulse-v${VERSION}-linux-armv7.tar.gz"
- "pulse-v${VERSION}.tar.gz"
- "checksums.txt"
-)
-
-for artifact in "${ARTIFACTS[@]}"; do
- echo -n "Checking $artifact: "
- URL="https://github.com/rcourtman/Pulse/releases/download/v${VERSION}/${artifact}"
- if curl -s -f -I "$URL" > /dev/null 2>&1; then
- echo -e "${GREEN}✓${NC}"
- else
- echo -e "${YELLOW}Not yet uploaded${NC}"
- fi
-done
-
-echo ""
-echo "3. DOCKER IMAGE AVAILABILITY"
-echo "============================"
-
-echo -n "Docker Hub image exists: "
-if curl -s "https://hub.docker.com/v2/repositories/rcourtman/pulse/tags/v${VERSION}" | grep -q "v${VERSION}"; then
- echo -e "${GREEN}✓${NC}"
-else
- echo -e "${YELLOW}Not yet pushed${NC}"
-fi
-
-echo ""
-echo "4. SYSTEMD SERVICE FILE"
-echo "======================="
-
-echo -n "Service file exists locally: "
-if [ -f /etc/systemd/system/pulse.service ] || [ -f /etc/systemd/system/pulse-backend.service ]; then
- echo -e "${GREEN}✓${NC}"
-
- # Check service file contents
- SERVICE_FILE=$(ls /etc/systemd/system/pulse*.service 2>/dev/null | head -1)
-
- echo -n "Service has Restart=always: "
- if grep -q "Restart=always" "$SERVICE_FILE"; then
- echo -e "${GREEN}✓${NC}"
- else
- echo -e "${RED}✗${NC}"
- fi
-
- echo -n "Service runs as pulse user: "
- if grep -q "User=pulse" "$SERVICE_FILE"; then
- echo -e "${GREEN}✓${NC}"
- else
- echo -e "${YELLOW}⚠️ Running as different user${NC}"
- fi
-else
- echo -e "${YELLOW}Not installed via systemd${NC}"
-fi
-
-echo ""
-echo "5. BINARY COMPATIBILITY TESTS"
-echo "============================="
-
-echo -n "Current binary runs: "
-if /opt/pulse/pulse help > /dev/null 2>&1; then
- echo -e "${GREEN}✓${NC}"
-else
- echo -e "${RED}✗${NC}"
-fi
-
-echo -n "Binary has embedded frontend: "
-if strings /opt/pulse/pulse 2>/dev/null | grep -q ""; then
- echo -e "${GREEN}✓${NC}"
-else
- echo -e "${RED}✗ Frontend not embedded!${NC}"
-fi
-
-echo ""
-echo "6. CONFIGURATION VALIDATION"
-echo "==========================="
-
-echo -n "Config directory exists: "
-if [ -d /etc/pulse ]; then
- echo -e "${GREEN}✓${NC}"
-
- echo -n ".env file exists: "
- if [ -f /etc/pulse/.env ]; then
- echo -e "${GREEN}✓${NC}"
- else
- echo -e "${YELLOW}Using defaults${NC}"
- fi
-
- echo -n "nodes.json exists: "
- if [ -f /etc/pulse/nodes.json ]; then
- echo -e "${GREEN}✓${NC}"
- else
- echo -e "${YELLOW}No nodes configured${NC}"
- fi
-else
- echo -e "${RED}✗${NC}"
-fi
-
-echo ""
-echo "7. PERMISSION CHECKS"
-echo "==================="
-
-echo -n "Pulse user exists: "
-if id pulse > /dev/null 2>&1; then
- echo -e "${GREEN}✓${NC}"
-
- echo -n "Config owned by pulse user: "
- if [ -d /etc/pulse ] && [ "$(stat -c %U /etc/pulse)" = "pulse" ]; then
- echo -e "${GREEN}✓${NC}"
- else
- echo -e "${YELLOW}⚠️ Ownership issue${NC}"
- fi
-else
- echo -e "${YELLOW}Running as different user${NC}"
-fi
-
-echo ""
-echo "8. PORT AVAILABILITY"
-echo "==================="
-
-echo -n "Port 7655 is listening: "
-if netstat -tln 2>/dev/null | grep -q :7655 || ss -tln 2>/dev/null | grep -q :7655; then
- echo -e "${GREEN}✓${NC}"
-else
- echo -e "${RED}✗ Not listening${NC}"
-fi
-
-echo ""
-echo "9. UPDATE MECHANISM"
-echo "=================="
-
-echo -n "Can detect current version: "
-CURRENT=$(curl -s http://localhost:7655/api/version 2>/dev/null | jq -r .version 2>/dev/null)
-if [ -n "$CURRENT" ]; then
- echo -e "${GREEN}✓ ($CURRENT)${NC}"
-else
- echo -e "${RED}✗${NC}"
-fi
-
-echo -n "Can check for updates: "
-if curl -s http://localhost:7655/api/updates/check 2>/dev/null | grep -q "currentVersion"; then
- echo -e "${GREEN}✓${NC}"
-else
- echo -e "${YELLOW}Requires auth${NC}"
-fi
-
-echo ""
-echo "================================================"
-echo "Installation tests complete"
-echo "================================================"
\ No newline at end of file
diff --git a/scripts/test-proxy-scenarios.sh b/scripts/test-proxy-scenarios.sh
deleted file mode 100755
index 9907e62ea..000000000
--- a/scripts/test-proxy-scenarios.sh
+++ /dev/null
@@ -1,176 +0,0 @@
-#!/bin/bash
-
-# Test script for reverse proxy scenarios
-# These are the cases that often break in production
-
-set -e
-
-PULSE_URL=${1:-http://localhost:7655}
-API_TOKEN=${2:-""}
-
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[1;33m'
-NC='\033[0m'
-
-echo "================================================"
-echo "REVERSE PROXY SCENARIO TESTING"
-echo "================================================"
-
-FAILED=0
-PASSED=0
-
-test_scenario() {
- local test_name="$1"
- local command="$2"
-
- echo -n "$test_name: "
- if eval "$command" > /dev/null 2>&1; then
- echo -e "${GREEN}✓${NC}"
- ((PASSED++)) || true
- else
- echo -e "${RED}✗${NC}"
- ((FAILED++)) || true
- fi
-}
-
-echo ""
-echo "1. NGINX-STYLE PROXY HEADERS"
-echo "============================"
-
-test_scenario "X-Real-IP header" \
- "curl -s -H 'X-Real-IP: 192.168.1.100' $PULSE_URL/api/health | grep -q healthy"
-
-test_scenario "X-Forwarded-For with multiple IPs" \
- "curl -s -H 'X-Forwarded-For: 203.0.113.0, 198.51.100.0, 172.16.0.1' $PULSE_URL/api/health | grep -q healthy"
-
-test_scenario "X-Forwarded-Proto https" \
- "curl -s -H 'X-Forwarded-Proto: https' $PULSE_URL/api/health | grep -q healthy"
-
-test_scenario "X-Forwarded-Host" \
- "curl -s -H 'X-Forwarded-Host: pulse.example.com' $PULSE_URL/api/health | grep -q healthy"
-
-test_scenario "X-Forwarded-Port" \
- "curl -s -H 'X-Forwarded-Port: 443' $PULSE_URL/api/health | grep -q healthy"
-
-echo ""
-echo "2. CLOUDFLARE TUNNEL HEADERS"
-echo "============================="
-
-test_scenario "CF-Connecting-IP" \
- "curl -s -H 'CF-Connecting-IP: 198.51.100.42' $PULSE_URL/api/health | grep -q healthy"
-
-test_scenario "CF-IPCountry" \
- "curl -s -H 'CF-IPCountry: US' $PULSE_URL/api/health | grep -q healthy"
-
-test_scenario "CF-Ray (request ID)" \
- "curl -s -H 'CF-Ray: 8a9b7c6d5e4f3a2b1' $PULSE_URL/api/health | grep -q healthy"
-
-test_scenario "CF-Visitor (scheme)" \
- "curl -s -H 'CF-Visitor: {\"scheme\":\"https\"}' $PULSE_URL/api/health | grep -q healthy"
-
-echo ""
-echo "3. TRAEFIK HEADERS"
-echo "=================="
-
-test_scenario "X-Forwarded-Prefix (subpath)" \
- "curl -s -H 'X-Forwarded-Prefix: /apps/pulse' $PULSE_URL/api/health | grep -q healthy"
-
-test_scenario "X-Forwarded-Method override" \
- "curl -s -H 'X-Forwarded-Method: POST' $PULSE_URL/api/health | grep -q healthy"
-
-echo ""
-echo "4. PATH VARIATIONS (CRITICAL FOR #334)"
-echo "======================================="
-
-# These are the exact scenarios that broke with issue #334
-test_scenario "Root without slash - no redirect" \
- "! curl -s -I $PULSE_URL | grep -q 'Location: ./'"
-
-test_scenario "Root with slash - no redirect" \
- "! curl -s -I $PULSE_URL/ | grep -q 'Location: ./'"
-
-test_scenario "Root without slash - 200 OK" \
- "curl -s -o /dev/null -w '%{http_code}' $PULSE_URL | grep -q 200"
-
-test_scenario "Root with slash - 200 OK" \
- "curl -s -o /dev/null -w '%{http_code}' $PULSE_URL/ | grep -q 200"
-
-# Test that we don't get relative redirects for any common paths
-PATHS=("" "/" "/api" "/api/" "/settings" "/login" "/dashboard")
-for path in "${PATHS[@]}"; do
- test_scenario "No relative redirect for '$path'" \
- "! curl -s -I '$PULSE_URL$path' 2>/dev/null | grep -i 'location:' | grep -q '^\\.'"
-done
-
-echo ""
-echo "5. WEBSOCKET THROUGH PROXY"
-echo "==========================="
-
-test_scenario "WebSocket with proxy headers" \
- "curl -s -I -H 'Upgrade: websocket' -H 'X-Forwarded-For: 10.0.0.1' $PULSE_URL/ws | grep -q 'HTTP/1.1'"
-
-test_scenario "WebSocket with wrong origin" \
- "curl -s -I -H 'Upgrade: websocket' -H 'Origin: http://evil.com' $PULSE_URL/ws | grep -q 'HTTP/1.1'"
-
-echo ""
-echo "6. AUTHENTICATION WITH PROXY"
-echo "============================="
-
-if [ -n "$API_TOKEN" ]; then
- test_scenario "API token through proxy headers" \
- "curl -s -H 'X-API-Token: $API_TOKEN' -H 'X-Forwarded-For: 10.0.0.1' $PULSE_URL/api/state | grep -q nodes"
-
- test_scenario "API token with Cloudflare headers" \
- "curl -s -H 'X-API-Token: $API_TOKEN' -H 'CF-Connecting-IP: 1.2.3.4' $PULSE_URL/api/state | grep -q nodes"
-else
- echo -e "${YELLOW}Skipping auth tests (no API_TOKEN)${NC}"
-fi
-
-echo ""
-echo "7. COOKIE HANDLING THROUGH PROXY"
-echo "================================="
-
-# Test that cookies work correctly with proxy headers (important for auth)
-test_scenario "Set-Cookie with secure flag for https proxy" \
- "curl -s -I -H 'X-Forwarded-Proto: https' $PULSE_URL | grep -i 'set-cookie' || true"
-
-echo ""
-echo "8. CONTENT-TYPE PRESERVATION"
-echo "============================="
-
-test_scenario "JSON content-type preserved" \
- "curl -s -I $PULSE_URL/api/version | grep -q 'Content-Type: application/json'"
-
-test_scenario "HTML content-type for UI" \
- "curl -s -I $PULSE_URL/ | grep -q 'Content-Type: text/html'"
-
-echo ""
-echo "9. SUBPATH DEPLOYMENT"
-echo "====================="
-
-# Test if Pulse could work behind a subpath (like /monitoring/pulse/)
-test_scenario "API works with referer containing subpath" \
- "curl -s -H 'Referer: https://example.com/monitoring/pulse/' $PULSE_URL/api/health | grep -q healthy"
-
-echo ""
-echo "10. COMPRESSION HANDLING"
-echo "========================"
-
-test_scenario "Accepts gzip encoding" \
- "curl -s -H 'Accept-Encoding: gzip' -I $PULSE_URL/ | grep -i 'content-encoding' || true"
-
-test_scenario "Handles deflate encoding request" \
- "curl -s -H 'Accept-Encoding: deflate' $PULSE_URL/api/health | grep -q healthy"
-
-echo ""
-echo "================================================"
-echo "RESULTS: Passed: $PASSED | Failed: $FAILED"
-echo "================================================"
-
-if [ $FAILED -gt 0 ]; then
- echo -e "${RED}⚠️ Some proxy scenarios failed!${NC}"
- exit 1
-else
- echo -e "${GREEN}✅ All proxy scenarios handled correctly${NC}"
-fi
\ No newline at end of file
diff --git a/scripts/test-release.sh b/scripts/test-release.sh
deleted file mode 100755
index e65103052..000000000
--- a/scripts/test-release.sh
+++ /dev/null
@@ -1,281 +0,0 @@
-#!/bin/bash
-
-# Comprehensive release testing script for Pulse
-# Tests actual deployments, not just unit tests
-
-set -e
-
-VERSION=${1:-$(cat VERSION)}
-PULSE_URL=${PULSE_URL:-http://localhost:7655}
-API_TOKEN=${API_TOKEN:-""}
-
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[1;33m'
-NC='\033[0m'
-
-echo "================================================"
-echo "Pulse Release Test Suite v${VERSION}"
-echo "================================================"
-
-# Detect if auth is disabled
-AUTH_DISABLED=false
-security_status=$(curl -s "$PULSE_URL/api/security/status" 2>/dev/null || echo "{}")
-if echo "$security_status" | grep -q '"disabled":true'; then
- AUTH_DISABLED=true
- echo ""
- echo -e "${YELLOW}Note: Authentication is DISABLED (DISABLE_AUTH mode)${NC}"
-fi
-
-# Track test results
-FAILED_TESTS=()
-PASSED_TESTS=()
-
-# Test function
-run_test() {
- local test_name="$1"
- local test_command="$2"
-
- echo -n "Testing: $test_name... "
- if eval "$test_command" > /dev/null 2>&1; then
- echo -e "${GREEN}✓${NC}"
- PASSED_TESTS+=("$test_name")
- else
- echo -e "${RED}✗${NC}"
- FAILED_TESTS+=("$test_name")
- fi
-}
-
-# Test function with output
-run_test_verbose() {
- local test_name="$1"
- local test_command="$2"
-
- echo "Testing: $test_name..."
- if eval "$test_command"; then
- echo -e "${GREEN}✓ $test_name passed${NC}"
- PASSED_TESTS+=("$test_name")
- else
- echo -e "${RED}✗ $test_name failed${NC}"
- FAILED_TESTS+=("$test_name")
- fi
-}
-
-echo ""
-echo "1. HTTP/ROUTING TESTS"
-echo "===================="
-
-# Critical: Test root without trailing slash (catches issue #334)
-run_test "Root path without trailing slash (no redirect)" \
- "curl -s -I ${PULSE_URL} | grep -q 'HTTP/1.1 200'"
-
-run_test "Root path with trailing slash" \
- "curl -s -I ${PULSE_URL}/ | grep -q 'HTTP/1.1 200'"
-
-# Check for unwanted redirects
-run_test "No relative path redirects" \
- "! curl -s -I ${PULSE_URL} | grep -q 'Location: ./'"
-
-# Test static assets (get actual filenames from index.html)
-JS_FILE=$(curl -s ${PULSE_URL}/ | grep -o '/assets/index-[^"]*\.js' | head -1)
-CSS_FILE=$(curl -s ${PULSE_URL}/ | grep -o '/assets/index-[^"]*\.css' | head -1)
-
-if [ -n "$JS_FILE" ]; then
- run_test "JavaScript assets load" \
- "curl -s -I ${PULSE_URL}${JS_FILE} | grep -q 'Content-Type: application/javascript'"
-else
- echo -e "${RED}✗ Could not find JS file${NC}"
- FAILED_TESTS+=("JavaScript assets load")
-fi
-
-if [ -n "$CSS_FILE" ]; then
- run_test "CSS assets load" \
- "curl -s -I ${PULSE_URL}${CSS_FILE} | grep -q 'Content-Type: text/css'"
-else
- echo -e "${RED}✗ Could not find CSS file${NC}"
- FAILED_TESTS+=("CSS assets load")
-fi
-
-# Test various access patterns
-run_test "Empty path handling" \
- "curl -s -o /dev/null -w '%{http_code}' ${PULSE_URL} | grep -q '200'"
-
-if [ "$AUTH_DISABLED" != true ]; then
- run_test "SPA routes require authentication" \
- "curl -s ${PULSE_URL}/settings | grep -q 'Authentication required'"
-else
- run_test "SPA routes accessible (auth disabled)" \
- "curl -s ${PULSE_URL}/settings | grep -q ''"
-fi
-
-echo ""
-echo "2. API ENDPOINT TESTS"
-echo "===================="
-
-# Public endpoints (should work without auth)
-run_test "API health endpoint" \
- "curl -s ${PULSE_URL}/api/health | grep -q 'healthy'"
-
-run_test "API version endpoint" \
- "curl -s ${PULSE_URL}/api/version | grep -q 'version'"
-
-# If API token provided, test protected endpoints
-if [ -n "$API_TOKEN" ]; then
- echo "Testing with API token..."
-
- run_test "API state with token" \
- "curl -s -H 'X-API-Token: $API_TOKEN' ${PULSE_URL}/api/state | grep -q 'nodes'"
-
- run_test "API config/nodes with token" \
- "curl -s -H 'X-API-Token: $API_TOKEN' ${PULSE_URL}/api/config/nodes | jq -e '. | type == \"array\"'"
-
- run_test "API export requires passphrase" \
- "curl -s -X POST -H 'X-API-Token: $API_TOKEN' ${PULSE_URL}/api/config/export -d '{}' | grep -q 'Passphrase is required'"
-else
- echo -e "${YELLOW}Skipping auth tests (no API_TOKEN provided)${NC}"
-fi
-
-echo ""
-echo "3. WEBSOCKET TESTS"
-echo "=================="
-
-# Test WebSocket endpoint availability
-run_test "WebSocket endpoint responds" \
- "curl -s -I -H 'Upgrade: websocket' ${PULSE_URL}/ws | grep -q 'HTTP/1.1'"
-
-echo ""
-echo "4. REVERSE PROXY SIMULATION"
-echo "==========================="
-
-# Simulate reverse proxy headers
-run_test "Handles X-Forwarded headers" \
- "curl -s -H 'X-Forwarded-For: 10.0.0.1' -H 'X-Forwarded-Proto: https' ${PULSE_URL}/api/health | grep -q 'healthy'"
-
-run_test "Handles proxy without trailing slash" \
- "curl -s -H 'X-Forwarded-Host: proxy.example.com' ${PULSE_URL} | grep -q '
'"
-
-echo ""
-echo "5. DOCKER DEPLOYMENT TEST (if Docker available)"
-echo "=============================================="
-
-if false && command -v docker &> /dev/null; then # Temporarily disabled - hanging
- echo "Testing Docker deployment..."
-
- # Stop any existing test container
- docker stop pulse-test 2>/dev/null || true
- docker rm pulse-test 2>/dev/null || true
-
- # Run test container
- echo "Starting Docker container..."
- docker run -d --name pulse-test \
- -p 7656:7655 \
- -e API_TOKEN=test123 \
- rcourtman/pulse:v${VERSION} > /dev/null 2>&1
-
- # Wait for container to start
- sleep 5
-
- run_test "Docker container running" \
- "docker ps | grep -q pulse-test"
-
- run_test "Docker health endpoint" \
- "curl -s http://localhost:7656/api/health | grep -q 'healthy'"
-
- run_test "Docker UI loads" \
- "curl -s http://localhost:7656 | grep -q 'Pulse'"
-
- # Cleanup
- docker stop pulse-test > /dev/null 2>&1
- docker rm pulse-test > /dev/null 2>&1
-else
- echo -e "${YELLOW}Docker not available, skipping Docker tests${NC}"
-fi
-
-echo ""
-echo "6. LXC DEPLOYMENT TEST (if on Proxmox)"
-echo "====================================="
-
-if command -v pct &> /dev/null; then
- echo "Would test LXC deployment (implement based on environment)"
- # This would create a test container, install Pulse, and verify
-else
- echo -e "${YELLOW}Not on Proxmox, skipping LXC tests${NC}"
-fi
-
-echo ""
-echo "7. UPDATE MECHANISM TEST"
-echo "======================="
-
-# Update check
-if [ "$AUTH_DISABLED" = true ]; then
- run_test "Update check endpoint (auth disabled)" \
- "curl -s ${PULSE_URL}/api/updates/check | jq -e '.currentVersion'"
-elif [ -n "$API_TOKEN" ]; then
- run_test "Update check endpoint with auth" \
- "curl -s -H 'X-API-Token: $API_TOKEN' ${PULSE_URL}/api/updates/check | jq -e '.currentVersion'"
-else
- run_test "Update check requires auth" \
- "curl -s ${PULSE_URL}/api/updates/check | grep -q 'Authentication required'"
-fi
-
-echo ""
-echo "8. PERFORMANCE TESTS"
-echo "==================="
-
-# Test response times
-RESPONSE_TIME=$(curl -s -o /dev/null -w '%{time_total}' ${PULSE_URL}/api/health)
-if (( $(echo "$RESPONSE_TIME < 1" | bc -l) )); then
- echo -e "${GREEN}✓ API response time: ${RESPONSE_TIME}s${NC}"
- PASSED_TESTS+=("API response time")
-else
- echo -e "${RED}✗ API slow: ${RESPONSE_TIME}s${NC}"
- FAILED_TESTS+=("API response time")
-fi
-
-echo ""
-echo "9. ERROR HANDLING TESTS"
-echo "======================"
-
-# 401 is returned before 404 when not authenticated (auth checked first)
-if [ "$AUTH_DISABLED" = true ]; then
- run_test "404 for non-existent endpoint" \
- "curl -s -o /dev/null -w '%{http_code}' ${PULSE_URL}/api/nonexistent | grep -q '404'"
-elif [ -n "$API_TOKEN" ]; then
- run_test "404 for non-existent API endpoint" \
- "curl -s -o /dev/null -w '%{http_code}' -H 'X-API-Token: $API_TOKEN' ${PULSE_URL}/api/nonexistent | grep -q '404'"
-else
- run_test "401 for non-existent endpoint (auth first)" \
- "curl -s -o /dev/null -w '%{http_code}' ${PULSE_URL}/api/nonexistent | grep -q '401'"
-fi
-
-run_test "405 for wrong method" \
- "curl -s -X DELETE -o /dev/null -w '%{http_code}' ${PULSE_URL}/api/health | grep -q '405'"
-
-echo ""
-echo "================================================"
-echo "TEST RESULTS SUMMARY"
-echo "================================================"
-echo -e "${GREEN}Passed: ${#PASSED_TESTS[@]} tests${NC}"
-echo -e "${RED}Failed: ${#FAILED_TESTS[@]} tests${NC}"
-
-if [ ${#FAILED_TESTS[@]} -gt 0 ]; then
- echo ""
- echo "Failed tests:"
- for test in "${FAILED_TESTS[@]}"; do
- echo " - $test"
- done
- echo ""
- echo -e "${RED}⚠️ RELEASE TESTS FAILED - DO NOT RELEASE!${NC}"
- exit 1
-else
- echo ""
- echo -e "${GREEN}✅ All tests passed! Safe to release.${NC}"
-fi
-
-echo ""
-echo "Additional manual tests recommended:"
-echo " 1. Test behind actual reverse proxy (nginx/traefik)"
-echo " 2. Test with Cloudflare tunnel"
-echo " 3. Test ProxmoxVE 'update' command"
-echo " 4. Test on different architectures (ARM)"
-echo " 5. Test upgrade from previous version"
\ No newline at end of file
diff --git a/scripts/test-security.sh b/scripts/test-security.sh
deleted file mode 100755
index 8a268bb50..000000000
--- a/scripts/test-security.sh
+++ /dev/null
@@ -1,268 +0,0 @@
-#!/bin/bash
-
-# Security testing for Pulse
-# Tests authentication, authorization, input validation, etc.
-# Detects auth state and adjusts expectations
-
-set -e
-
-PULSE_URL=${1:-http://localhost:7655}
-API_TOKEN=${2:-""}
-
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-YELLOW='\033[1;33m'
-NC='\033[0m'
-
-echo "================================================"
-echo "SECURITY TESTING"
-echo "================================================"
-
-VULNERABILITIES=0
-
-# Detect if auth is disabled
-AUTH_DISABLED=false
-security_status=$(curl -s "$PULSE_URL/api/security/status" 2>/dev/null || echo "{}")
-if echo "$security_status" | grep -q '"disabled":true'; then
- AUTH_DISABLED=true
- echo ""
- echo -e "${YELLOW}Note: Authentication is DISABLED (DISABLE_AUTH mode)${NC}"
- echo -e "${YELLOW}Skipping auth bypass tests${NC}"
-fi
-
-test_security() {
- local test_name="$1"
- local command="$2"
- local expected="$3"
-
- echo -n "$test_name: "
- RESULT=$(eval "$command" 2>/dev/null || echo "ERROR")
- if [[ "$RESULT" == *"$expected"* ]]; then
- echo -e "${GREEN}✓ Secure${NC}"
- else
- echo -e "${RED}✗ VULNERABLE${NC}"
- ((VULNERABILITIES++))
- fi
-}
-
-echo ""
-echo "1. AUTHENTICATION BYPASS ATTEMPTS"
-echo "================================="
-
-if [ "$AUTH_DISABLED" != true ]; then
- test_security "Empty auth header" \
- "curl -s -H 'X-API-Token: ' $PULSE_URL/api/state | head -1" \
- "Authentication required"
-
- test_security "Null token" \
- "curl -s -H 'X-API-Token: null' $PULSE_URL/api/state | head -1" \
- "Authentication required"
-
- test_security "SQL injection in token" \
- "curl -s -H \"X-API-Token: ' OR '1'='1\" $PULSE_URL/api/state | head -1" \
- "Authentication required"
-
- test_security "Command injection in token" \
- "curl -s -H 'X-API-Token: \$(whoami)' $PULSE_URL/api/state | head -1" \
- "Authentication required"
-
- test_security "Path traversal in token" \
- "curl -s -H 'X-API-Token: ../../etc/passwd' $PULSE_URL/api/state | head -1" \
- "Authentication required"
-else
- echo -e "${YELLOW}Skipped - auth is disabled${NC}"
-fi
-
-echo ""
-echo "2. PATH TRAVERSAL ATTEMPTS"
-echo "=========================="
-
-if [ "$AUTH_DISABLED" != true ]; then
- test_security "Path traversal in URL" \
- "curl -s -o /dev/null -w '%{http_code}' $PULSE_URL/../../../etc/passwd" \
- "401" # 401 is fine - auth blocks before path processing
-
- test_security "Double URL encoding" \
- "curl -s -o /dev/null -w '%{http_code}' $PULSE_URL/%252e%252e%252f%252e%252e%252fetc%252fpasswd" \
- "401" # 401 is secure - auth blocks first
-
- test_security "Null byte injection" \
- "curl -s -o /dev/null -w '%{http_code}' '$PULSE_URL/api/health%00.json'" \
- "401" # Expected - auth required
-else
- # When auth is disabled, server returns 200 (index page) for invalid paths
- test_security "Path traversal in URL" \
- "curl -s -o /dev/null -w '%{http_code}' $PULSE_URL/../../../etc/passwd" \
- "200" # Returns index page, not actual file
-
- test_security "Double URL encoding" \
- "curl -s -o /dev/null -w '%{http_code}' $PULSE_URL/%252e%252e%252f%252e%252e%252fetc%252fpasswd" \
- "200" # Returns index page
-
- test_security "Null byte injection" \
- "curl -s -o /dev/null -w '%{http_code}' '$PULSE_URL/api/health%00.json'" \
- "404" # API endpoint with null byte returns 404
-fi
-
-echo ""
-echo "3. XSS ATTEMPTS"
-echo "==============="
-
-test_security "XSS in query parameter" \
- "curl -s '$PULSE_URL/api/health?test=' | grep -c '' $PULSE_URL | grep -c '' | grep -c '