#!/usr/bin/env bash # ===================================================== # Installer JSON API Test Script # ===================================================== # Tests all API endpoints and verifies functionality set -Eeuo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Source libraries source "${SCRIPT_DIR}/libsupabase.sh" source "${SCRIPT_DIR}/lib_installer_json_api.sh" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Test counters TESTS_PASSED=0 TESTS_FAILED=0 TESTS_TOTAL=0 # Test configuration TEST_CTID="${TEST_CTID:-769697636}" TEST_EMAIL="${TEST_EMAIL:-test@example.com}" TEST_POSTGREST_URL="${TEST_POSTGREST_URL:-http://192.168.45.104:3000}" TEST_SERVICE_ROLE_KEY="${TEST_SERVICE_ROLE_KEY:-}" # Usage usage() { cat < Test CTID (default: 769697636) --email Test email (default: test@example.com) --postgrest-url PostgREST URL (default: http://192.168.45.104:3000) --service-role-key Service role key for authenticated tests --help Show this help Examples: # Basic test (public endpoints only) bash test_installer_json_api.sh # Full test with authentication bash test_installer_json_api.sh --service-role-key "eyJhbGc..." # Test specific instance bash test_installer_json_api.sh --ctid 769697636 --email max@beispiel.de EOF } # Parse arguments while [[ $# -gt 0 ]]; do case "$1" in --ctid) TEST_CTID="${2:-}"; shift 2 ;; --email) TEST_EMAIL="${2:-}"; shift 2 ;; --postgrest-url) TEST_POSTGREST_URL="${2:-}"; shift 2 ;; --service-role-key) TEST_SERVICE_ROLE_KEY="${2:-}"; shift 2 ;; --help|-h) usage; exit 0 ;; *) echo "Unknown option: $1"; usage; exit 1 ;; esac done # Print functions print_header() { echo -e "\n${BLUE}========================================${NC}" echo -e "${BLUE}$1${NC}" echo -e "${BLUE}========================================${NC}\n" } print_test() { echo -e "${YELLOW}TEST $((TESTS_TOTAL + 1)):${NC} $1" } print_pass() { echo -e "${GREEN}✓ PASS${NC}: $1" ((TESTS_PASSED++)) ((TESTS_TOTAL++)) } print_fail() { echo -e "${RED}✗ FAIL${NC}: $1" ((TESTS_FAILED++)) ((TESTS_TOTAL++)) } print_skip() { echo -e "${YELLOW}⊘ SKIP${NC}: $1" } print_info() { echo -e "${BLUE}ℹ INFO${NC}: $1" } # Test functions test_api_connectivity() { print_test "API Connectivity" local response local http_code response=$(curl -sS -w "\n%{http_code}" -X POST "${TEST_POSTGREST_URL}/rpc/get_public_config" \ -H "Content-Type: application/json" \ -d '{}' 2>&1 || echo -e "\nFAILED") http_code=$(echo "$response" | tail -n1) if [[ "$http_code" == "200" ]]; then print_pass "API is reachable (HTTP 200)" else print_fail "API is not reachable (HTTP ${http_code})" fi } test_public_config() { print_test "Get Public Config" local response response=$(get_public_config "${TEST_POSTGREST_URL}" 2>/dev/null || echo "") if [[ -n "$response" ]]; then # Check if response contains expected fields if echo "$response" | grep -q "registration_webhook_url"; then print_pass "Public config retrieved successfully" print_info "Response: ${response}" else print_fail "Public config missing expected fields" fi else print_fail "Failed to retrieve public config" fi } test_get_instance_by_email() { print_test "Get Instance Config by Email" local response response=$(get_installer_json_by_email "${TEST_EMAIL}" "${TEST_POSTGREST_URL}" 2>/dev/null || echo "") if [[ -n "$response" && "$response" != "[]" ]]; then # Check if response contains expected fields if echo "$response" | grep -q "ctid"; then print_pass "Instance config retrieved by email" # Verify no secrets are exposed if echo "$response" | grep -qE "password|service_role_key|jwt_secret|encryption_key"; then print_fail "Response contains secrets (SECURITY ISSUE!)" else print_pass "No secrets exposed in response" fi # Print sample of response local ctid ctid=$(echo "$response" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d[0]['ctid'] if d else 'N/A')" 2>/dev/null || echo "N/A") print_info "Found CTID: ${ctid}" else print_fail "Instance config missing expected fields" fi else print_skip "No instance found for email: ${TEST_EMAIL} (this is OK if instance doesn't exist)" fi } test_get_instance_by_ctid() { print_test "Get Instance Config by CTID (requires service role key)" if [[ -z "$TEST_SERVICE_ROLE_KEY" ]]; then print_skip "Service role key not provided (use --service-role-key)" return fi local response response=$(get_installer_json_by_ctid "${TEST_CTID}" "${TEST_POSTGREST_URL}" "${TEST_SERVICE_ROLE_KEY}" 2>/dev/null || echo "") if [[ -n "$response" && "$response" != "[]" ]]; then # Check if response contains expected fields if echo "$response" | grep -q "ctid"; then print_pass "Instance config retrieved by CTID" # Verify no secrets are exposed if echo "$response" | grep -qE "password|service_role_key|jwt_secret|encryption_key"; then print_fail "Response contains secrets (SECURITY ISSUE!)" else print_pass "No secrets exposed in response" fi else print_fail "Instance config missing expected fields" fi else print_skip "No instance found for CTID: ${TEST_CTID} (this is OK if instance doesn't exist)" fi } test_store_installer_json() { print_test "Store Installer JSON (requires service role key)" if [[ -z "$TEST_SERVICE_ROLE_KEY" ]]; then print_skip "Service role key not provided (use --service-role-key)" return fi # Create test JSON local test_json test_json=$(cat </dev/null || echo "") if [[ -n "$response" && "$response" != "[]" ]]; then print_pass "Stored data can be retrieved" # Verify secrets are NOT in the response if echo "$response" | grep -q "TEST_PASSWORD_SHOULD_NOT_BE_EXPOSED"; then print_fail "CRITICAL: Passwords are exposed in API response!" elif echo "$response" | grep -q "TEST_SERVICE_ROLE_KEY_SHOULD_NOT_BE_EXPOSED"; then print_fail "CRITICAL: Service role key is exposed in API response!" elif echo "$response" | grep -q "TEST_JWT_SECRET_SHOULD_NOT_BE_EXPOSED"; then print_fail "CRITICAL: JWT secret is exposed in API response!" elif echo "$response" | grep -q "TEST_ENCRYPTION_KEY_SHOULD_NOT_BE_EXPOSED"; then print_fail "CRITICAL: Encryption key is exposed in API response!" else print_pass "SECURITY: All secrets are properly filtered" fi else print_fail "Stored data could not be retrieved" fi else print_skip "Failed to store installer JSON (instance may not exist in database)" fi } test_cors_headers() { print_test "CORS Headers" local response response=$(curl -sS -I -X OPTIONS "${TEST_POSTGREST_URL}/rpc/get_public_config" \ -H "Origin: https://botkonzept.de" \ -H "Access-Control-Request-Method: POST" 2>&1 || echo "") if echo "$response" | grep -qi "access-control-allow-origin"; then print_pass "CORS headers are present" else print_skip "CORS headers not found (may need configuration)" fi } test_rate_limiting() { print_test "Rate Limiting (optional)" print_skip "Rate limiting test not implemented (should be configured at nginx/gateway level)" } test_response_format() { print_test "Response Format Validation" local response response=$(get_public_config "${TEST_POSTGREST_URL}" 2>/dev/null || echo "") if [[ -n "$response" ]]; then # Validate JSON format if echo "$response" | python3 -m json.tool >/dev/null 2>&1; then print_pass "Response is valid JSON" else print_fail "Response is not valid JSON" fi else print_fail "No response received" fi } # Main test execution main() { print_header "BotKonzept Installer JSON API Tests" echo "Test Configuration:" echo " CTID: ${TEST_CTID}" echo " Email: ${TEST_EMAIL}" echo " PostgREST URL: ${TEST_POSTGREST_URL}" echo " Service Role Key: ${TEST_SERVICE_ROLE_KEY:+***provided***}" echo "" # Run tests test_api_connectivity test_public_config test_response_format test_cors_headers test_get_instance_by_email test_get_instance_by_ctid test_store_installer_json test_rate_limiting # Print summary print_header "Test Summary" echo "Total Tests: ${TESTS_TOTAL}" echo -e "${GREEN}Passed: ${TESTS_PASSED}${NC}" echo -e "${RED}Failed: ${TESTS_FAILED}${NC}" echo "" if [[ $TESTS_FAILED -eq 0 ]]; then echo -e "${GREEN}✓ All tests passed!${NC}" exit 0 else echo -e "${RED}✗ Some tests failed${NC}" exit 1 fi } # Run main main