#!/bin/bash # ═══════════════════════════════════════════════════════════════ # L99 AUTH EXHAUSTIVE v6.0 — ALL SERVICES + ALL PAGES # Tests: login/logout flows, all subdomains, all protected pages # Cron: */6h | Alerte: Telegram + Groq # ═══════════════════════════════════════════════════════════════ LOG="/var/log/wevia-director/l99-sso.log" RESULT="/var/log/wevia-director/l99-sso-latest.json" mkdir -p /var/log/wevia-director DATE=$(date "+%Y-%m-%d %H:%M") P=0; F=0; T=0; FAILS="" ok(){ T=$((T+1)); P=$((P+1)); } fail(){ T=$((T+1)); F=$((F+1)); FAILS="$FAILS\n• $1"; } test_http(){ CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 -k "https://127.0.0.1$2" -H "Host: $1" 2>/dev/null) [ "$CODE" = "$3" ] && ok || fail "$1$2 expected=$3 got=$CODE" } # ═══ SECTION 1: WEVAL AUTH SYSTEM ═══ # 1.1 Auth files for f in weval-auth.php weval-login.php weval-auth-check.php weval-logout.php; do [ -f "/var/www/html/auth/$f" ] && ok || fail "missing /auth/$f" done # 1.2 Login page LP=$(curl -s --max-time 5 -k "https://127.0.0.1/login" -H "Host: weval-consulting.com" 2>/dev/null | grep -c "Se connecter") [ "$LP" -ge 1 ] && ok || fail "login page broken" # 1.3 Login flow E2E curl -s -c /tmp/l99c --max-time 5 -k "https://127.0.0.1/login?r=/architecture.html" -H "Host: weval-consulting.com" -d "user=yacine&pass=Weval@2026" -o /dev/null 2>/dev/null A=$(curl -s -b /tmp/l99c --max-time 5 -k "https://127.0.0.1/architecture.html" -H "Host: weval-consulting.com" -o /dev/null -w "%{http_code}" 2>/dev/null) [ "$A" = "200" ] && ok || fail "login flow (got $A)" # 1.4 Logout L=$(curl -s -b /tmp/l99c --max-time 5 -k "https://127.0.0.1/logout" -H "Host: weval-consulting.com" -o /dev/null -w "%{http_code}" 2>/dev/null) [ "$L" = "302" ] && ok || fail "logout ($L)" # 1.5 Zero Authentik refs AK=$(grep -rl "goauthentik\|outpost" /etc/nginx/sites-enabled/ 2>/dev/null | grep -v ".bak\|.gold" | wc -l) [ "$AK" = "0" ] && ok || fail "authentik refs ($AK files)" # 1.6 Nginx immutable lsattr /etc/nginx/sites-enabled/weval-consulting 2>/dev/null | grep -q "\-i\-" && ok || fail "nginx not immutable" # ═══ SECTION 2: ALL PROTECTED PAGES ═══ PAGES=$(grep "auth_request /auth/check" /etc/nginx/sites-enabled/weval-consulting 2>/dev/null | grep "location" | sed "s/.*location[= ]*//" | sed "s/ {.*//" | grep -v "^~" | sort -u) for page in $PAGES; do T=$((T+1)) CN=$(curl -s --max-time 5 -o /dev/null -w "%{http_code}" -k "https://127.0.0.1$page" -H "Host: weval-consulting.com" 2>/dev/null) CA=$(curl -s -b /tmp/l99c --max-time 5 -o /dev/null -w "%{http_code}" -k "https://127.0.0.1$page" -H "Host: weval-consulting.com" 2>/dev/null) # Login first for valid cookie curl -s -c /tmp/l99c --max-time 3 -k "https://127.0.0.1/login?r=/" -H "Host: weval-consulting.com" -d "user=yacine&pass=Weval@2026" -o /dev/null 2>/dev/null CA=$(curl -s -b /tmp/l99c --max-time 5 -o /dev/null -w "%{http_code}" -k "https://127.0.0.1$page" -H "Host: weval-consulting.com" 2>/dev/null) [ "$CN" = "302" ] && [ "$CA" != "302" ] && P=$((P+1)) || { F=$((F+1)); FAILS="$FAILS\n• $page (no=$CN auth=$CA)"; } done # ═══ SECTION 3: ALL SUBDOMAINS ACCESSIBLE ═══ for d in mm.weval-consulting.com analytics.weval-consulting.com n8n.weval-consulting.com monitor.weval-consulting.com crm.weval-consulting.com paperclip.weval-consulting.com mirofish.weval-consulting.com deerflow.weval-consulting.com wevads.weval-consulting.com; do T=$((T+1)) CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 -k "https://127.0.0.1" -H "Host: $d" 2>/dev/null) [ "$CODE" = "200" ] || [ "$CODE" = "302" ] || [ "$CODE" = "301" ] && P=$((P+1)) || { F=$((F+1)); FAILS="$FAILS\n• $d HTTP:$CODE"; } done # ═══ SECTION 4: DOCKER SERVICES ═══ for c in mattermost plausible n8n uptime-kuma twenty; do T=$((T+1)) docker ps --format "{{.Names}}" | grep -q "^${c}$" && P=$((P+1)) || { F=$((F+1)); FAILS="$FAILS\n• docker:$c DOWN"; } done # ═══ SECTION 5: WEDROID AUTH ═══ T=$((T+1)) WD=$(curl -s --max-time 5 -k "https://127.0.0.1/wevia-ia/wevia-admin.php" -H "Host: weval-consulting.com" -u "yacine:Weval@2026" 2>/dev/null | grep -c "OK") [ "$WD" -ge 1 ] && P=$((P+1)) || { F=$((F+1)); FAILS="$FAILS\n• wedroid auth broken"; } rm -f /tmp/l99c # ═══ RESULTS ═══ [ "$T" = "0" ] && T=1 S=$((P*100/T)) echo "{\"date\":\"$DATE\",\"total\":$T,\"pass\":$P,\"fail\":$F,\"score\":$S,\"version\":\"v6.0\"}" > "$RESULT" echo "[$DATE] L99-AUTH-v6: $P/$T ($S%)" >> "$LOG" if [ $F -gt 0 ]; then TG=$(cat /etc/weval/tg_bot_token 2>/dev/null) [ -n "$TG" ] && curl -s "https://api.telegram.org/bot${TG}/sendMessage" -d "chat_id=7605775322" --data-urlencode "text=⚠️ L99-AUTH-v6: $P/$T ($S%)\n$FAILS" >/dev/null 2>&1 echo "L99-AUTH-v6: $P/$T ($S%) ❌"; echo -e "FAILS:$FAILS" else echo "L99-AUTH-v6: $P/$T ($S%) ✅" fi exit $F