Обновить autoXRAY.sh

This commit is contained in:
2026-05-26 12:22:49 +00:00
parent 0af5a329c6
commit dcb32e7e0b
+67 -66
View File
@@ -158,6 +158,9 @@ map $http_user_agent $axray_bad_bot {
} }
SECEOF SECEOF
echo "${configPageUser}:$(openssl passwd -apr1 "${configPagePass}")" > /etc/nginx/conf.d/autoXRAY-htpasswd echo "${configPageUser}:$(openssl passwd -apr1 "${configPagePass}")" > /etc/nginx/conf.d/autoXRAY-htpasswd
NGINX_USER=$(ps -eo user,comm | awk '$2=="nginx" && $1!="root" {print $1; exit}')
NGINX_USER=${NGINX_USER:-www-data}
chown root:"$NGINX_USER" /etc/nginx/conf.d/autoXRAY-htpasswd
chmod 640 /etc/nginx/conf.d/autoXRAY-htpasswd chmod 640 /etc/nginx/conf.d/autoXRAY-htpasswd
bash -c "cat > $CONFIG_PATH" <<EOF bash -c "cat > $CONFIG_PATH" <<EOF
@@ -715,88 +718,86 @@ CONFIGS_ARRAY=(
"VLESS XHTTP REALITY EXTRA (для моста)|$linkRTY2" "VLESS XHTTP REALITY EXTRA (для моста)|$linkRTY2"
"VLESS RAW REALITY VISION|$linkRTY1" "VLESS RAW REALITY VISION|$linkRTY1"
) )
ALL_LINKS_TEXT="" # --- ЗАПИСЬ HTML-СТРАНИЦЫ (HEAD + СТАТИЧЕСКИЙ JS/CSS) ---
cat > "$WEB_PATH/$path_subpage.html" <<'HTMLEOF'
# --- ЗАПИСЬ HEAD (СТАТИКА, МИНИФИЦИРОВАННЫЕ СТИЛИ И JS) --- <!DOCTYPE html><html lang="ru"><head>
cat > "$WEB_PATH/$path_subpage.html" <<'EOF' <meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><meta name="robots" content="noindex,nofollow">
<!DOCTYPE html><html lang="ru"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>autoXRAY</title>
<meta name="robots" content="noindex,nofollow">
<title>autoXRAY configs</title>
<link rel="icon" type="image/svg+xml" href='data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDBCRkZGIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTIxIDJsLTIgMm0tNy42MSA3LjYxYTUuNSA1LjUgMCAxIDEtNy43NzggNy43NzggNS41IDUuNSAwIDAgMSA3Ljc3Ny03Ljc3N3ptMCAwTDE1LjUgNy41bTAgMGwzIDNMMjIgN2wtMy0zbS0zLjUgMy41TDE5IDQiLz48L3N2Zz4='> <link rel="icon" type="image/svg+xml" href='data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDBCRkZGIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTIxIDJsLTIgMm0tNy42MSA3LjYxYTUuNSA1LjUgMCAxIDEtNy43NzggNy43NzggNS41IDUuNSAwIDAgMSA3Ljc3Ny03Ljc3N3ptMCAwTDE1LjUgNy41bTAgMGwzIDNMMjIgN2wtMy0zbS0zLjUgMy41TDE5IDQiLz48L3N2Zz4='>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
<style> <style>
body{font-family:monospace;background:#121212;color:#e0e0e0;padding:10px;max-width:900px;margin:0 auto}h2{color:#c3e88d;border-top:2px solid #333;padding-top:20px;margin:15px 0 10px;font-size:18px}.config-row{background:#1e1e1e;border:1px solid #333;border-radius:6px;padding:5px;display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:8px}.config-label{background:#2c2c2c;color:#82aaff;padding:6px 10px;border-radius:4px;font-weight:700;font-size:13px;white-space:nowrap;min-width:140px;text-align:center}.config-code{flex:1;white-space:nowrap;overflow-x:auto;padding:8px;background:#121212;border-radius:4px;color:#c3e88d;font-size:12px;scrollbar-width:none}.config-code::-webkit-scrollbar{display:none}.btn-action{border:1px solid #555;padding:6px 12px;border-radius:4px;cursor:pointer;font-weight:700;font-size:12px;transition:all .2s;height:32px;display:flex;align-items:center;justify-content:center}.copy-btn{background:#333;color:#e0e0e0;min-width:60px}.copy-btn:hover{background:#c3e88d;color:#121212;border-color:#c3e88d}.qr-btn{background:#333;color:#82aaff;border-color:#82aaff;min-width:40px}.qr-btn:hover{background:#82aaff;color:#121212}.btn-group{display:flex;gap:10px;margin:10px 0 20px}.btn{flex:1;background:#2c2c2c;color:#c3e88d;border:1px solid #c3e88d;padding:10px;text-align:center;border-radius:6px;text-decoration:none;font-weight:700;font-size:14px}.btn:hover{background:#c3e88d;color:#121212}.btn.download{border-color:#82aaff;color:#82aaff}.btn.download:hover{background:#82aaff;color:#121212}.btn.tg{border-color:#2AABEE;color:#2AABEE}.btn.tg:hover{background:#2AABEE;color:#fff}.modal-overlay{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.85);z-index:999;justify-content:center;align-items:center;backdrop-filter:blur(3px)}.modal-content{background:#1e1e1e;padding:20px;border-radius:10px;border:1px solid #82aaff;text-align:center}#qrcode{background:#fff;padding:10px;border-radius:6px;margin-bottom:10px}.close-modal-btn{background:#c31e1e;color:#fff;border:none;padding:8px 20px;border-radius:4px;cursor:pointer}@media(max-width:600px){.config-label{width:100%;margin-bottom:2px}.config-code{min-width:100%;order:3}.btn-action{flex:1;order:2}} :root{--bg:#0d0d0f;--sf:#18181b;--bd:#27272a;--tx:#f4f4f5;--mt:#71717a;--gn:#4ade80;--ac:#6366f1}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:var(--bg);color:var(--tx);min-height:100vh;padding:24px 16px}
.w{max-width:680px;margin:0 auto}
header{text-align:center;padding:40px 0 36px}
header h1{font-size:22px;font-weight:700;letter-spacing:-.5px;background:linear-gradient(135deg,#c7d2fe,#a5b4fc);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
header p{color:var(--mt);font-size:13px;margin-top:6px}
.card{background:var(--sf);border:1px solid var(--bd);border-radius:16px;padding:20px;margin-bottom:12px;transition:border-color .2s,box-shadow .2s}
.card:hover{border-color:#3f3f46;box-shadow:0 0 0 1px #3f3f4640}
.ct{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
.badge{font-size:10.5px;font-weight:600;padding:4px 11px;border-radius:20px;background:rgba(99,102,241,.1);color:#a5b4fc;border:1px solid rgba(99,102,241,.2);letter-spacing:.4px;text-transform:uppercase}
.bts{display:flex;gap:7px}
.ib{width:34px;height:34px;border-radius:9px;border:1px solid var(--bd);background:transparent;color:var(--mt);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .15s;flex-shrink:0}
.ib:hover{background:#27272a;color:var(--tx);border-color:#3f3f46}
.ib.ok{background:rgba(74,222,128,.08);color:var(--gn);border-color:rgba(74,222,128,.25)}
.ib svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.cfg{font-family:ui-monospace,'SF Mono','Fira Code',monospace;font-size:11.5px;color:#a1a1aa;background:rgba(0,0,0,.35);border:1px solid var(--bd);border-radius:10px;padding:12px 14px;word-break:break-all;line-height:1.7;filter:blur(4px);user-select:none;transition:filter .3s;pointer-events:none}
.cfg.show{filter:none;user-select:text;pointer-events:auto}
.modal{display:none;position:fixed;inset:0;background:rgba(0,0,0,.72);z-index:99;justify-content:center;align-items:center;backdrop-filter:blur(8px)}
.modal.on{display:flex}
.mbox{background:var(--sf);border:1px solid var(--bd);border-radius:18px;padding:28px 24px;text-align:center}
#qrc{background:#fff;padding:12px;border-radius:10px;margin-bottom:16px;display:inline-block}
.mc{background:#ef4444;color:#fff;border:none;padding:8px 26px;border-radius:9px;cursor:pointer;font-weight:600;font-size:13px;transition:opacity .15s}
.mc:hover{opacity:.85}
footer{text-align:center;padding:40px 0 20px;color:var(--mt);font-size:12px}
footer a{color:var(--ac);text-decoration:none}
@media(max-width:480px){.card{padding:16px}.cfg{font-size:11px}.badge{font-size:10px}}
</style> </style>
<script> <script>
function copyText(e,t){navigator.clipboard.writeText(document.getElementById(e).innerText).then(()=>{let o=t.innerText;t.innerText="OK",t.style.cssText="background:#c3e88d;color:#121212",setTimeout(()=>{t.innerText=o,t.style.cssText=""},1500)}).catch(e=>console.error(e))}function showQR(e){let t=document.getElementById(e).innerText,o=document.getElementById("qrModal"),n=document.getElementById("qrcode");n.innerHTML="",new QRCode(n,{text:t,width:256,height:256,colorDark:"#000000",colorLight:"#ffffff",correctLevel:QRCode.CorrectLevel.L}),o.style.display="flex"}function closeModal(){document.getElementById("qrModal").style.display="none"}window.onclick=function(e){e.target==document.getElementById("qrModal")&&closeModal()}; var EO='<svg viewBox="0 0 24 24"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>';
</script> var EX='<svg viewBox="0 0 24 24"><path d="M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19m-6.72-1.07a3 3 0 11-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg>';
</head><body> var CP='<svg viewBox="0 0 24 24"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg>';
EOF var CK='<svg viewBox="0 0 24 24" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg>';
var QI='<svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><path d="M14 14h3v3m3-3v3m0 3h-6m3 0v-3"/></svg>';
function toggleVis(id,b){var e=document.getElementById(id),on=e.classList.toggle('show');b.classList.toggle('ok',on);b.innerHTML=on?EX:EO;b.title=on?'Скрыть':'Показать';}
function doCopy(id,b){navigator.clipboard.writeText(document.getElementById(id).innerText).then(function(){var o=b.innerHTML;b.innerHTML=CK;b.classList.add('ok');setTimeout(function(){b.innerHTML=o;b.classList.remove('ok');},1500);});}
function doQR(id){var t=document.getElementById(id).innerText;document.getElementById('qrc').innerHTML='';new QRCode(document.getElementById('qrc'),{text:t,width:240,height:240,colorDark:'#000',colorLight:'#fff',correctLevel:QRCode.CorrectLevel.L});document.getElementById('modal').classList.add('on');}
function closeModal(){document.getElementById('modal').classList.remove('on');}
window.onclick=function(e){if(e.target.id==='modal')closeModal();};
</script></head><body>
<div class="w">
<header><h1>autoXRAY</h1><p>Конфигурации прокси-клиента</p></header>
HTMLEOF
# --- ЗАПИСЬ BODY (ДИНАМИЧЕСКИЕ ДАННЫЕ) --- # --- ДИНАМИЧЕСКИЕ КАРТОЧКИ КОНФИГОВ ---
cat >> "$WEB_PATH/$path_subpage.html" <<EOF
<h2>📂 Ссылка на подписку (готовый конфиг клиента с роутингом)</h2>
<div class="config-row">
<div class="config-label">Subscription</div>
<div class="config-code" id="subLink">$subPageLink</div>
<button class="btn-action copy-btn" onclick="copyText('subLink', this)">Copy</button>
<button class="btn-action qr-btn" onclick="showQR('subLink')">QR</button>
</div>
<h2>📱 Приложение HAPP (Windows/Android/iOS/MAC/Linux)</h2>
<div class="btn-group">
<a href="happ://add/$subPageLink" class="btn">⚡ Add to HAPP</a>
<a href="https://www.happ.su/main/ru" target="_blank" class="btn download">⬇️ Download App</a>
</div>
<p>Маршрутизацию нужно выключить, она тут встроенная. По умолчанию она выключена - включается, если вы пользовались сторонними сервисами.</p>
<h2>➡️ Конфиги</h2>
EOF
# Цикл генерации строк конфигов
idx=1 idx=1
for item in "${CONFIGS_ARRAY[@]}"; do for item in "${CONFIGS_ARRAY[@]}"; do
title="${item%%|*}" title="${item%%|*}"
link="${item#*|}" link="${item#*|}"
cat >> "$WEB_PATH/$path_subpage.html" <<CARDEOF
if [ -z "$ALL_LINKS_TEXT" ]; then ALL_LINKS_TEXT="$link"; else ALL_LINKS_TEXT="$ALL_LINKS_TEXT<br>$link"; fi <div class="card">
<div class="ct">
cat >> "$WEB_PATH/$path_subpage.html" <<EOF <span class="badge">$title</span>
<div class="config-row"> <div class="bts">
<div class="config-label">$title</div> <button class="ib" title="Показать" onclick="toggleVis('c${idx}',this)"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></button>
<div class="config-code" id="c$idx">$link</div> <button class="ib" title="Копировать" onclick="doCopy('c${idx}',this)"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg></button>
<button class="btn-action copy-btn" onclick="copyText('c$idx', this)">Copy</button> <button class="ib" title="QR-код" onclick="doQR('c${idx}')"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><path d="M14 14h3v3m3-3v3m0 3h-6m3 0v-3"/></svg></button>
<button class="btn-action qr-btn" onclick="showQR('c$idx')">QR</button> </div>
</div>
<div class="cfg" id="c${idx}">$link</div>
</div> </div>
EOF CARDEOF
((idx++)) ((idx++))
done done
# Дописываем Socks5, All links и подвал # --- ПОДВАЛ И МОДАЛКА ---
cat >> "$WEB_PATH/$path_subpage.html" <<EOF cat >> "$WEB_PATH/$path_subpage.html" <<'HTMLEOF'
<div class="config-row"> <footer><a href="https://github.com/xVRVx/autoXRAY">github.com/xVRVx/autoXRAY</a></footer>
<div class="config-label">Socks5 (TG)</div>
<div class="config-code" id="sock">server=$DOMAIN port=10443 user=${socksUser} pass=${socksPasw}</div>
<button class="btn-action copy-btn" onclick="copyText('sock', this)">Copy</button>
<a href="https://t.me/socks?server=$DOMAIN&port=10443&user=${socksUser}&pass=${socksPasw}" target="_blank" class="btn-action qr-btn" title="автодобавление в тг" style="text-decoration:none">✈️ Add to TG</a>
</div> </div>
<div id="modal" class="modal"><div class="mbox"><div id="qrc"></div><button class="mc" onclick="closeModal()">Закрыть</button></div></div>
<h2>💠 Все конфиги вместе</h2>
<div class="config-row">
<div class="config-code" id="cAll" style="max-height:60px;white-space:pre-wrap;word-break:break-all">$ALL_LINKS_TEXT</div>
<button class="btn-action copy-btn" onclick="copyText('cAll', this)">Copy ALL</button>
<button class="btn-action qr-btn" onclick="showQR('cAll')">QR</button>
</div>
<div><a style="color:white;margin:40px auto 20px;display:block;text-align:center;" href="https://github.com/xVRVx/autoXRAY">https://github.com/xVRVx/autoXRAY</a></div>
<div id="qrModal" class="modal-overlay"><div class="modal-content"><div id="qrcode"></div><button class="close-modal-btn" onclick="closeModal()">Close</button></div></div>
</body></html> </body></html>
EOF HTMLEOF
# --- ФИНАЛЬНАЯ ПРОВЕРКА --- # --- ФИНАЛЬНАЯ ПРОВЕРКА ---
echo -e "\n${YEL}=== Финальная проверка статусов ===${NC}" echo -e "\n${YEL}=== Финальная проверка статусов ===${NC}"