Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
- ADD_CHAIN138_TO_LEDGER_LIVE: Ledger form done; public code review repo bis-innovations/LedgerLive; init/push commands - CONTRACT_DEPLOYMENT_RUNBOOK: Chain 138 gas price 1 gwei, 36-addr check, TransactionMirror workaround - CONTRACT_*: AddressMapper, MirrorManager deployed 2026-02-12; 36-address on-chain check - NEXT_STEPS_FOR_YOU: Ledger done; steps completable now (no LAN); run-completable-tasks-from-anywhere - MASTER_INDEX, OPERATOR_OPTIONAL, SMART_CONTRACTS_INVENTORY_SIMPLE: updates - LEDGER_BLOCKCHAIN_INTEGRATION_COMPLETE: bis-innovations/LedgerLive reference Co-authored-by: Cursor <cursoragent@cursor.com>
142 lines
5.5 KiB
Bash
Executable File
142 lines
5.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Fix Content Security Policy headers in NPMplus
|
|
# Updates CSP to allow unsafe-eval and fixes Quirks Mode issues
|
|
|
|
set -euo pipefail
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[✗]${NC} $1"; }
|
|
|
|
NPM_URL="${1:-https://192.168.0.166:81}"
|
|
NPM_EMAIL="${2:-nsatoshi2007@hotmail.com}"
|
|
NPM_PASSWORD="${3:-ce8219e321e1cd97bd590fb792d3caeb7e2e3b94ca7e20124acaf253f911ff72}"
|
|
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo "🔒 NPMplus CSP Headers Fix"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
|
|
# Authenticate
|
|
log_info "Authenticating to NPMplus API..."
|
|
TOKEN_RESPONSE=$(curl -s -k -X POST "$NPM_URL/api/tokens" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{
|
|
\"identity\": \"$NPM_EMAIL\",
|
|
\"secret\": \"$NPM_PASSWORD\"
|
|
}")
|
|
|
|
TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.token // empty' 2>/dev/null || echo "")
|
|
|
|
if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
|
|
ERROR_MSG=$(echo "$TOKEN_RESPONSE" | jq -r '.error.message // "Unknown error"' 2>/dev/null || echo "Unknown error")
|
|
log_error "Failed to authenticate: $ERROR_MSG"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "Authenticated successfully"
|
|
echo ""
|
|
|
|
# Get all proxy hosts
|
|
log_info "Fetching proxy hosts..."
|
|
PROXY_HOSTS_JSON=$(curl -s -k -X GET "$NPM_URL/api/nginx/proxy-hosts" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json")
|
|
|
|
PROXY_COUNT=$(echo "$PROXY_HOSTS_JSON" | jq -r 'length' 2>/dev/null || echo "0")
|
|
log_info "Found $PROXY_COUNT proxy hosts"
|
|
echo ""
|
|
|
|
# CSP configuration that allows unsafe-eval (for development/legacy apps)
|
|
CSP_HEADER="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: data:; style-src 'self' 'unsafe-inline' https: data:; font-src 'self' https: data:; img-src 'self' data: https: blob:; connect-src 'self' https: wss: ws:; media-src 'self' https: data:; object-src 'none'; base-uri 'self'; form-action 'self' https:; frame-ancestors 'none'; upgrade-insecure-requests"
|
|
|
|
# Advanced config with proper headers
|
|
ADVANCED_CONFIG="# Security Headers
|
|
add_header X-Content-Type-Options \"nosniff\" always;
|
|
add_header X-Frame-Options \"SAMEORIGIN\" always;
|
|
add_header X-XSS-Protection \"1; mode=block\" always;
|
|
add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;
|
|
add_header Content-Security-Policy \"$CSP_HEADER\" always;
|
|
|
|
# Ensure proper DOCTYPE (if backend doesn't provide it)
|
|
# Note: This requires backend to send proper DOCTYPE, Nginx can't modify HTML body easily"
|
|
|
|
success_count=0
|
|
fail_count=0
|
|
|
|
echo "$PROXY_HOSTS_JSON" | jq -c '.[]' 2>/dev/null | while IFS= read -r host; do
|
|
host_id=$(echo "$host" | jq -r '.id')
|
|
domain=$(echo "$host" | jq -r '.domain_names[0] // empty' 2>/dev/null || echo "")
|
|
|
|
if [ -z "$domain" ] || [ "$domain" = "null" ]; then
|
|
continue
|
|
fi
|
|
|
|
# Skip test domains
|
|
if echo "$domain" | grep -q "test.*example.com"; then
|
|
continue
|
|
fi
|
|
|
|
log_info "Updating: $domain (Host ID: $host_id)"
|
|
|
|
# Get current configuration
|
|
CURRENT_HOST=$(curl -s -k -X GET "$NPM_URL/api/nginx/proxy-hosts/$host_id" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json")
|
|
|
|
# Merge advanced_config
|
|
CURRENT_ADVANCED=$(echo "$CURRENT_HOST" | jq -r '.advanced_config // ""' 2>/dev/null || echo "")
|
|
|
|
# Check if CSP is already configured
|
|
if echo "$CURRENT_ADVANCED" | grep -q "Content-Security-Policy"; then
|
|
log_info " CSP already configured, skipping..."
|
|
continue
|
|
fi
|
|
|
|
# Update only advanced_config field (NPMplus API requires minimal payload)
|
|
UPDATE_PAYLOAD=$(jq -n --arg config "$ADVANCED_CONFIG" \
|
|
'{advanced_config: $config}' 2>/dev/null || echo "")
|
|
|
|
UPDATE_RESPONSE=$(curl -s -k -X PUT "$NPM_URL/api/nginx/proxy-hosts/$host_id" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$UPDATE_PAYLOAD")
|
|
|
|
UPDATE_ID=$(echo "$UPDATE_RESPONSE" | jq -r '.id // empty' 2>/dev/null || echo "")
|
|
|
|
if [ -n "$UPDATE_ID" ] && [ "$UPDATE_ID" != "null" ]; then
|
|
log_success " ✓ Updated CSP headers"
|
|
success_count=$((success_count + 1))
|
|
else
|
|
ERROR=$(echo "$UPDATE_RESPONSE" | jq -r '.error.message // .error // "Unknown error"' 2>/dev/null || echo "Unknown error")
|
|
log_warn " Failed: $ERROR"
|
|
fail_count=$((fail_count + 1))
|
|
fi
|
|
|
|
echo ""
|
|
sleep 1 # Rate limiting
|
|
done
|
|
|
|
# Summary
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
log_info "Summary:"
|
|
log_success " Updated: $success_count"
|
|
log_warn " Failed: $fail_count"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
|
|
log_info "Note:"
|
|
log_info " - CSP now allows 'unsafe-eval' for legacy JavaScript"
|
|
log_info " - Quirks Mode issue requires backend to send proper DOCTYPE"
|
|
log_info " - Backend services should include: <!DOCTYPE html>"
|
|
echo ""
|