#!/bin/bash set -euo pipefail # TEST-203: iframe/new-tab verification for all apps. # Checks X-Frame-Options headers and verifies mustOpenInNewTab() mapping. SSH_KEY="${ARCHIPELAGO_SSH_KEY:-$HOME/.ssh/archipelago-deploy}" TARGET="archipelago@192.168.1.228" SSH_CMD="ssh -i $SSH_KEY -o StrictHostKeyChecking=no $TARGET" # Apps that MUST open in new tab (X-Frame-Options: DENY or SAMEORIGIN) MUST_NEW_TAB="btcpay-server homeassistant nextcloud immich" # All apps and their ports for checking declare -A APP_PORTS=( [bitcoin-knots]="8332" [electrs]="50001" [btcpay-server]="23000" [lnd]="8080" [mempool]="18080" [homeassistant]="8123" [grafana]="3033" [searxng]="18888" [ollama]="11434" [onlyoffice]="8044" [penpot]="9001" [nextcloud]="8085" [vaultwarden]="8099" [jellyfin]="8096" [photoprism]="2342" [immich]="2283" [filebrowser]="18082" [nginx-proxy-manager]="8181" [portainer]="9443" [uptime-kuma]="3001" [fedimint]="8174" ) PASS=0 FAIL=0 SKIP=0 RESULTS=() log() { echo -e "\033[1;34m[TEST]\033[0m $*"; } pass() { echo -e "\033[1;32m[PASS]\033[0m $*"; PASS=$((PASS + 1)); RESULTS+=("PASS: $*"); } fail() { echo -e "\033[1;31m[FAIL]\033[0m $*"; FAIL=$((FAIL + 1)); RESULTS+=("FAIL: $*"); } skip() { echo -e "\033[1;33m[SKIP]\033[0m $*"; SKIP=$((SKIP + 1)); RESULTS+=("SKIP: $*"); } check_app() { local app_id="$1" local port="${APP_PORTS[$app_id]}" local should_newtab=false for nt in $MUST_NEW_TAB; do if [ "$nt" = "$app_id" ]; then should_newtab=true break fi done # Check if port responds local headers headers=$($SSH_CMD "curl -sI --connect-timeout 5 http://localhost:$port/ 2>/dev/null" || echo "") if [ -z "$headers" ]; then skip "$app_id (port $port) — not responding (app may not be running)" return fi # Check X-Frame-Options header local xfo xfo=$(echo "$headers" | grep -i "x-frame-options" | head -1 | tr -d '\r' || echo "") local csp_frame csp_frame=$(echo "$headers" | grep -i "content-security-policy" | grep -i "frame-ancestors" | head -1 | tr -d '\r' || echo "") local blocks_iframe=false if echo "$xfo" | grep -qi "deny\|sameorigin"; then blocks_iframe=true fi if echo "$csp_frame" | grep -qi "frame-ancestors.*none\|frame-ancestors.*self"; then blocks_iframe=true fi if [ "$blocks_iframe" = true ]; then if [ "$should_newtab" = true ]; then pass "$app_id — correctly marked as new-tab (blocks iframe: $xfo)" else fail "$app_id — blocks iframe ($xfo) but NOT in mustOpenInNewTab()" fi else if [ "$should_newtab" = true ]; then log " INFO: $app_id is in mustOpenInNewTab() but doesn't block iframes (safe to keep)" pass "$app_id — marked as new-tab (conservative, OK)" else pass "$app_id — loads in iframe OK (no frame restrictions)" fi fi } main() { log "=== iframe/new-tab Verification Test ===" echo "" for app_id in $(echo "${!APP_PORTS[@]}" | tr ' ' '\n' | sort); do check_app "$app_id" done echo "" log "=== RESULTS ===" for r in "${RESULTS[@]}"; do echo " $r" done echo "" log "Pass: $PASS | Fail: $FAIL | Skip: $SKIP" [ $FAIL -gt 0 ] && exit 1 exit 0 } main "$@"