From 74ba6d7825741fe7965c91e5ccd8ae6d0436fe59 Mon Sep 17 00:00:00 2001 From: quydang <81231812+quydang04@users.noreply.github.com> Date: Sat, 20 Jan 2024 16:32:35 +0700 Subject: [PATCH 1/9] Add support for ARMv5 and x86 (#1642) --- .github/workflows/docker.yml | 4 ++-- .github/workflows/release.yml | 31 ++++++++++++++++++++++++++-- DockerInit.sh | 10 ++++++++- install.sh | 8 +++++-- web/translation/translate.vi_VN.toml | 4 ++-- 5 files changed, 48 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index b2dc0ca4..6afe8618 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,4 +1,4 @@ -name: Release 3X-UI dockerhub +name: Release 3X-UI for Docker on: push: tags: @@ -36,6 +36,6 @@ jobs: with: context: . push: ${{ github.event_name != 'pull_request' }} - platforms: linux/amd64, linux/arm64/v8, linux/arm/v7, linux/arm/v6 + platforms: linux/amd64, linux/arm64/v8, linux/arm/v7, linux/arm/v6, linux/386, linux/arm/v5 tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 91a7e093..62bc6e7c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,6 +15,8 @@ jobs: - arm64 - armv7 - armv6 + - 386 + - armv5 runs-on: ubuntu-20.04 steps: - name: Checkout repository @@ -30,8 +32,14 @@ jobs: sudo apt-get update if [ "${{ matrix.platform }}" == "arm64" ]; then sudo apt install gcc-aarch64-linux-gnu - elif [ "${{ matrix.platform }}" == "armv7" ] || [ "${{ matrix.platform }}" == "armv6" ]; then + elif [ "${{ matrix.platform }}" == "armv7" ]; then sudo apt install gcc-arm-linux-gnueabihf + elif [ "${{ matrix.platform }}" == "armv6" ]; then + sudo apt install gcc-arm-linux-gnueabihf + elif [ "${{ matrix.platform }}" == "386" ]; then + sudo apt install gcc-i686-linux-gnu + elif [ "${{ matrix.platform }}" == "armv5" ]; then + sudo apt install gcc-arm-linux-gnueabi fi - name: Build x-ui @@ -42,10 +50,21 @@ jobs: if [ "${{ matrix.platform }}" == "arm64" ]; then export GOARCH=arm64 export CC=aarch64-linux-gnu-gcc - elif [ "${{ matrix.platform }}" == "armv7" ] || [ "${{ matrix.platform }}" == "armv6" ]; then + elif [ "${{ matrix.platform }}" == "armv7" ]; then export GOARCH=arm export GOARM=7 export CC=arm-linux-gnueabihf-gcc + elif [ "${{ matrix.platform }}" == "armv6" ]; then + export GOARCH=arm + export GOARM=6 + export CC=arm-linux-gnueabihf-gcc + elif [ "${{ matrix.platform }}" == "386" ]; then + export GOARCH=386 + export CC=i686-linux-gnu-gcc + elif [ "${{ matrix.platform }}" == "armv5" ]; then + export GOARCH=arm + export GOARM=5 + export CC=arm-linux-gnueabi-gcc fi go build -o xui-release -v main.go @@ -75,6 +94,14 @@ jobs: wget ${Xray_URL}Xray-linux-arm32-v6.zip unzip Xray-linux-arm32-v6.zip rm -f Xray-linux-arm32-v6.zip + elif [ "${{ matrix.platform }}" == "386" ]; then + wget ${Xray_URL}Xray-linux-32.zip + unzip Xray-linux-32.zip + rm -f Xray-linux-32.zip + elif [ "${{ matrix.platform }}" == "armv5" ]; then + wget ${Xray_URL}Xray-linux-arm32-v5.zip + unzip Xray-linux-arm32-v5.zip + rm -f Xray-linux-arm32-v5.zip fi rm -f geoip.dat geosite.dat wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat diff --git a/DockerInit.sh b/DockerInit.sh index c62dc77e..bbfcb04e 100755 --- a/DockerInit.sh +++ b/DockerInit.sh @@ -5,6 +5,10 @@ case $1 in ARCH="64" FNAME="amd64" ;; + i386) + ARCH="32" + FNAME="i386" + ;; armv8 | arm64 | aarch64) ARCH="arm64-v8a" FNAME="arm64" @@ -17,6 +21,10 @@ case $1 in ARCH="arm32-v6" FNAME="armv6" ;; + armv5) + ARCH="arm32-v5" + FNAME="armv5" + ;; *) ARCH="64" FNAME="amd64" @@ -29,7 +37,7 @@ cd build/bin wget "https://github.com/XTLS/Xray-core/releases/download/v1.8.7/Xray-linux-${ARCH}.zip" unzip "Xray-linux-${ARCH}.zip" -rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat geoip_IR.dat geosite_IR.dat geoip_VN.dat geosite_VN.dat +rm -f "Xray-linux-${ARCH}.zip" geoip.dat geosite.dat mv xray "xray-linux-${FNAME}" wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat diff --git a/install.sh b/install.sh index 8d4a0c0c..8fd42ab8 100644 --- a/install.sh +++ b/install.sh @@ -26,12 +26,15 @@ echo "The OS release is: $release" arch3xui() { case "$(uname -m)" in x86_64 | x64 | amd64) echo 'amd64' ;; + i*86 | x86) echo '386' ;; armv8* | armv8 | arm64 | aarch64) echo 'arm64' ;; armv7* | armv7 | arm) echo 'armv7' ;; - armv6* | armv6 | arm) echo 'armv6' ;; + armv6* | armv6) echo 'armv6' ;; + armv5* | armv5) echo 'armv5' ;; *) echo -e "${green}Unsupported CPU architecture! ${plain}" && rm -f install.sh && exit 1 ;; esac } + echo "arch: $(arch3xui)" os_version="" @@ -163,7 +166,8 @@ install_x-ui() { chmod +x x-ui # Check the system's architecture and rename the file accordingly - if [[ $(arch3xui) == "armv6" || $(arch3xui) == "armv7" ]]; then + if [[ $(arch3xui) == "armv5" || $(arch3xui) == "armv6" || $(arch3xui) == "armv7" ]]; then + mv bin/xray-linux-$(arch3xui) bin/xray-linux-arm chmod +x bin/xray-linux-arm fi diff --git a/web/translation/translate.vi_VN.toml b/web/translation/translate.vi_VN.toml index d627254b..7491a70c 100644 --- a/web/translation/translate.vi_VN.toml +++ b/web/translation/translate.vi_VN.toml @@ -74,9 +74,9 @@ [pages.index] "title" = "Trạng thái hệ thống" -"memory" = "Bộ nhớ" +"memory" = "Ram" "hard" = "Dung lượng" -"xrayStatus" = "Trạng thái" +"xrayStatus" = "Trạng thái Xray" "stopXray" = "Dừng lại" "restartXray" = "Khởi động lại" "xraySwitch" = "Phiên bản" From 7f13adbd05b5a1fb5f71e99dcff41bb13814134f Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Sat, 20 Jan 2024 15:49:34 +0330 Subject: [PATCH 2/9] fail2ban - auto allowipv6 --- x-ui.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/x-ui.sh b/x-ui.sh index 2807bc4f..de7e1f9f 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -862,8 +862,11 @@ run_speedtest() { } create_iplimit_jails() { - # Use default bantime if not passed => 5 minutes - local bantime="${1:-5}" + # Use default bantime if not passed => 30 minutes + local bantime="${1:-30}" + + # uncomment allowipv6 = auto in fail2ban.conf + sed -i 's/#allowipv6 = auto/allowipv6 = auto/g' /etc/fail2ban/fail2ban.conf cat << EOF > /etc/fail2ban/jail.d/3x-ipl.conf [3x-ipl] From 38378fe36fbcaa8ca500fbc1fe1e8ea873dc248f Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Sat, 20 Jan 2024 16:38:54 +0330 Subject: [PATCH 3/9] update fail2ban v1.0.2 for debian --- install.sh | 30 +++++++++++++++--------------- x-ui.sh | 19 ++++++++++++++----- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/install.sh b/install.sh index 8fd42ab8..ae489c2a 100644 --- a/install.sh +++ b/install.sh @@ -81,19 +81,21 @@ fi install_base() { case "${release}" in - centos|fedora|almalinux|rocky) - yum -y update && yum install -y -q wget curl tar - ;; - arch|manjaro) - pacman -Syu && pacman -Syu --noconfirm wget curl tar - ;; - *) - apt-get update && apt install -y -q wget curl tar - ;; + centos | almalinux | rocky) + yum -y update && yum install -y -q wget curl tar + ;; + fedora) + dnf -y update && dnf install -y -q wget curl tar + ;; + arch | manjaro) + pacman -Syu && pacman -Syu --noconfirm wget curl tar + ;; + *) + apt-get update && apt install -y -q wget curl tar + ;; esac } - # This function will be called when user installed x-ui out of security config_after_install() { echo -e "${yellow}Install/update finished! For security it's recommended to modify panel settings ${plain}" @@ -167,11 +169,10 @@ install_x-ui() { # Check the system's architecture and rename the file accordingly if [[ $(arch3xui) == "armv5" || $(arch3xui) == "armv6" || $(arch3xui) == "armv7" ]]; then - - mv bin/xray-linux-$(arch3xui) bin/xray-linux-arm - chmod +x bin/xray-linux-arm + mv bin/xray-linux-$(arch3xui) bin/xray-linux-arm + chmod +x bin/xray-linux-arm fi - + chmod +x x-ui bin/xray-linux-$(arch3xui) cp -f x-ui.service /etc/systemd/system/ wget --no-check-certificate -O /usr/bin/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.sh @@ -201,7 +202,6 @@ install_x-ui() { echo -e "----------------------------------------------" } - echo -e "${green}Running...${plain}" install_base install_x-ui $1 diff --git a/x-ui.sh b/x-ui.sh index de7e1f9f..af63b9b4 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -982,12 +982,16 @@ iplimit_main() { install_iplimit() { if ! command -v fail2ban-client &>/dev/null; then echo -e "${green}Fail2ban is not installed. Installing now...!${plain}\n" + # Check the OS and install necessary packages case "${release}" in ubuntu|debian) - apt update && apt install fail2ban -y ;; + wget -O fail2ban.deb https://github.com/fail2ban/fail2ban/releases/download/1.0.2/fail2ban_1.0.2-1.upstream1_all.deb + wget -O fail2ban.deb.asc https://github.com/fail2ban/fail2ban/releases/download/1.0.2/fail2ban_1.0.2-1.upstream1_all.deb.asc + dpkg -i fail2ban.deb ;; centos|almalinux|rocky) - yum -y update && yum -y install fail2ban ;; + yum update -y && yum install epel-release -y + yum -y install fail2ban ;; fedora) dnf -y update && dnf -y install fail2ban ;; *) @@ -1027,6 +1031,7 @@ install_iplimit() { # Launching fail2ban if ! systemctl is-active --quiet fail2ban; then systemctl start fail2ban + systemctl enable fail2ban else systemctl restart fail2ban fi @@ -1054,11 +1059,15 @@ remove_iplimit(){ systemctl stop fail2ban case "${release}" in ubuntu|debian) - apt-get purge fail2ban -y;; + apt-get remove -y fail2ban + apt-get purge -y fail2ban -y + apt-get autoremove -y;; centos|almalinux|rocky) - yum remove fail2ban -y;; + yum remove fail2ban -y + yum autoremove -y;; fedora) - dnf remove fail2ban -y;; + dnf remove fail2ban -y + dnf autoremove -y;; *) echo -e "${red}Unsupported operating system. Please uninstall Fail2ban manually.${plain}\n" exit 1 ;; From a7bea936c536c560183e4577996e9a56b4cfd08a Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Sat, 20 Jan 2024 17:28:44 +0330 Subject: [PATCH 4/9] Update x-ui.sh --- x-ui.sh | 366 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 195 insertions(+), 171 deletions(-) diff --git a/x-ui.sh b/x-ui.sh index af63b9b4..cabb546f 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -70,13 +70,11 @@ elif [[ "${release}" == "armbian" ]]; then echo "Your OS is Armbian" fi - # Declare Variables log_folder="${XUI_LOG_FOLDER:=/var/log}" iplimit_log_path="${log_folder}/3xipl.log" iplimit_banned_log_path="${log_folder}/3xipl-banned.log" - confirm() { if [[ $# > 1 ]]; then echo && read -p "$1 [Default $2]: " temp @@ -140,7 +138,7 @@ custom_version() { if [ -z "$panel_version" ]; then echo "Panel version cannot be empty. Exiting." - exit 1 + exit 1 fi download_link="https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh" @@ -329,15 +327,15 @@ show_log() { } show_banlog() { - if test -f "${iplimit_banned_log_path}"; then - if [[ -s "${iplimit_banned_log_path}" ]]; then - cat ${iplimit_banned_log_path} + if test -f "${iplimit_banned_log_path}"; then + if [[ -s "${iplimit_banned_log_path}" ]]; then + cat ${iplimit_banned_log_path} + else + echo -e "${red}Log file is empty.${plain}\n" + fi else - echo -e "${red}Log file is empty.${plain}\n" + echo -e "${red}Log file not found. Please Install Fail2ban and IP Limit first.${plain}\n" fi - else - echo -e "${red}Log file not found. Please Install Fail2ban and IP Limit first.${plain}\n" - fi } enable_bbr() { @@ -348,19 +346,19 @@ enable_bbr() { # Check the OS and install necessary packages case "${release}" in - ubuntu|debian) - apt-get update && apt-get install -yqq --no-install-recommends ca-certificates - ;; - centos|almalinux|rocky) - yum -y update && yum -y install ca-certificates - ;; - fedora) - dnf -y update && dnf -y install ca-certificates - ;; - *) - echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n" - exit 1 - ;; + ubuntu | debian) + apt-get update && apt-get install -yqq --no-install-recommends ca-certificates + ;; + centos | almalinux | rocky) + yum -y update && yum -y install ca-certificates + ;; + fedora) + dnf -y update && dnf -y install ca-certificates + ;; + *) + echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n" + exit 1 + ;; esac # Enable BBR @@ -581,21 +579,24 @@ ssl_cert_issue_main() { echo -e "${green}\t0.${plain} Back to Main Menu" read -p "Choose an option: " choice case "$choice" in - 0) - show_menu ;; - 1) - ssl_cert_issue ;; - 2) - local domain="" - read -p "Please enter your domain name to revoke the certificate: " domain - ~/.acme.sh/acme.sh --revoke -d ${domain} - LOGI "Certificate revoked" - ;; - 3) - local domain="" - read -p "Please enter your domain name to forcefully renew an SSL certificate: " domain - ~/.acme.sh/acme.sh --renew -d ${domain} --force ;; - *) echo "Invalid choice" ;; + 0) + show_menu + ;; + 1) + ssl_cert_issue + ;; + 2) + local domain="" + read -p "Please enter your domain name to revoke the certificate: " domain + ~/.acme.sh/acme.sh --revoke -d ${domain} + LOGI "Certificate revoked" + ;; + 3) + local domain="" + read -p "Please enter your domain name to forcefully renew an SSL certificate: " domain + ~/.acme.sh/acme.sh --renew -d ${domain} --force + ;; + *) echo "Invalid choice" ;; esac } @@ -611,15 +612,19 @@ ssl_cert_issue() { fi # install socat second case "${release}" in - ubuntu|debian|armbian) - apt update && apt install socat -y ;; - centos|almalinux|rocky) - yum -y update && yum -y install socat ;; - fedora) - dnf -y update && dnf -y install socat ;; - *) - echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n" - exit 1 ;; + ubuntu | debian | armbian) + apt update && apt install socat -y + ;; + centos | almalinux | rocky) + yum -y update && yum -y install socat + ;; + fedora) + dnf -y update && dnf -y install socat + ;; + *) + echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n" + exit 1 + ;; esac if [ $? -ne 0 ]; then LOGE "install socat failed, please check logs" @@ -750,8 +755,8 @@ ssl_cert_issue_CF() { LOGI "Certificate issued Successfully, Installing..." fi ~/.acme.sh/acme.sh --installcert -d ${CF_Domain} -d *.${CF_Domain} --ca-file /root/cert/ca.cer \ - --cert-file /root/cert/${CF_Domain}.cer --key-file /root/cert/${CF_Domain}.key \ - --fullchain-file /root/cert/fullchain.cer + --cert-file /root/cert/${CF_Domain}.cer --key-file /root/cert/${CF_Domain}.key \ + --fullchain-file /root/cert/fullchain.cer if [ $? -ne 0 ]; then LOGE "Certificate installation failed, script exiting..." exit 1 @@ -782,21 +787,22 @@ warp_cloudflare() { echo -e "${green}\t0.${plain} Back to Main Menu" read -p "Choose an option: " choice case "$choice" in - 0) - show_menu ;; - 1) - bash <(curl -sSL https://raw.githubusercontent.com/hamid-gh98/x-ui-scripts/main/install_warp_proxy.sh) - ;; - 2) - warp a - ;; - 3) - warp y - ;; - 4) - warp u - ;; - *) echo "Invalid choice" ;; + 0) + show_menu + ;; + 1) + bash <(curl -sSL https://raw.githubusercontent.com/hamid-gh98/x-ui-scripts/main/install_warp_proxy.sh) + ;; + 2) + warp a + ;; + 3) + warp y + ;; + 4) + warp u + ;; + *) echo "Invalid choice" ;; esac } @@ -809,45 +815,46 @@ multi_protocol() { echo -e "${green}\t0.${plain} Back to Main Menu" read -p "Choose an option: " choice case "$choice" in - 0) - show_menu ;; - 1) - bash <(curl -Ls https://raw.githubusercontent.com/M4mmad/3xui-multi-protocol/master/install.sh --ipv4) - ;; - 2) - bash <(curl -Ls https://raw.githubusercontent.com/M4mmad/3xui-multi-protocol/master/unistall.sh --ipv4) - ;; - 3) - systemctl start 3xui-multi-protocol - ;; - 4) - systemctl stop 3xui-multi-protocol - ;; - *) echo "Invalid choice" ;; + 0) + show_menu + ;; + 1) + bash <(curl -Ls https://raw.githubusercontent.com/M4mmad/3xui-multi-protocol/master/install.sh --ipv4) + ;; + 2) + bash <(curl -Ls https://raw.githubusercontent.com/M4mmad/3xui-multi-protocol/master/unistall.sh --ipv4) + ;; + 3) + systemctl start 3xui-multi-protocol + ;; + 4) + systemctl stop 3xui-multi-protocol + ;; + *) echo "Invalid choice" ;; esac } run_speedtest() { # Check if Speedtest is already installed - if ! command -v speedtest &> /dev/null; then + if ! command -v speedtest &>/dev/null; then # If not installed, install it local pkg_manager="" local speedtest_install_script="" - - if command -v dnf &> /dev/null; then + + if command -v dnf &>/dev/null; then pkg_manager="dnf" speedtest_install_script="https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.rpm.sh" - elif command -v yum &> /dev/null; then + elif command -v yum &>/dev/null; then pkg_manager="yum" speedtest_install_script="https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.rpm.sh" - elif command -v apt-get &> /dev/null; then + elif command -v apt-get &>/dev/null; then pkg_manager="apt-get" speedtest_install_script="https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.deb.sh" - elif command -v apt &> /dev/null; then + elif command -v apt &>/dev/null; then pkg_manager="apt" speedtest_install_script="https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.deb.sh" fi - + if [[ -z $pkg_manager ]]; then echo "Error: Package manager not found. You may need to install Speedtest manually." return 1 @@ -938,65 +945,74 @@ iplimit_main() { echo -e "${green}\t0.${plain} Back to Main Menu" read -p "Choose an option: " choice case "$choice" in - 0) - show_menu ;; - 1) - confirm "Proceed with installation of Fail2ban & IP Limit?" "y" - if [[ $? == 0 ]]; then - install_iplimit - else - iplimit_main - fi ;; - 2) - read -rp "Please enter new Ban Duration in Minutes [default 5]: " NUM - if [[ $NUM =~ ^[0-9]+$ ]]; then - create_iplimit_jails ${NUM} - systemctl restart fail2ban - else - echo -e "${red}${NUM} is not a number! Please, try again.${plain}" - fi - iplimit_main ;; - 3) - confirm "Proceed with Unbanning everyone from IP Limit jail?" "y" - if [[ $? == 0 ]]; then - fail2ban-client reload --restart --unban 3x-ipl - echo -e "${green}All users Unbanned successfully.${plain}" - iplimit_main - else - echo -e "${yellow}Cancelled.${plain}" - fi - iplimit_main ;; - 4) - show_banlog - ;; - 5) - service fail2ban status - ;; + 0) + show_menu + ;; + 1) + confirm "Proceed with installation of Fail2ban & IP Limit?" "y" + if [[ $? == 0 ]]; then + install_iplimit + else + iplimit_main + fi + ;; + 2) + read -rp "Please enter new Ban Duration in Minutes [default 30]: " NUM + if [[ $NUM =~ ^[0-9]+$ ]]; then + create_iplimit_jails ${NUM} + systemctl restart fail2ban + else + echo -e "${red}${NUM} is not a number! Please, try again.${plain}" + fi + iplimit_main + ;; + 3) + confirm "Proceed with Unbanning everyone from IP Limit jail?" "y" + if [[ $? == 0 ]]; then + fail2ban-client reload --restart --unban 3x-ipl + echo -e "${green}All users Unbanned successfully.${plain}" + iplimit_main + else + echo -e "${yellow}Cancelled.${plain}" + fi + iplimit_main + ;; + 4) + show_banlog + ;; + 5) + service fail2ban status + ;; - 6) - remove_iplimit ;; - *) echo "Invalid choice" ;; + 6) + remove_iplimit + ;; + *) echo "Invalid choice" ;; esac } install_iplimit() { if ! command -v fail2ban-client &>/dev/null; then echo -e "${green}Fail2ban is not installed. Installing now...!${plain}\n" - + # Check the OS and install necessary packages case "${release}" in - ubuntu|debian) - wget -O fail2ban.deb https://github.com/fail2ban/fail2ban/releases/download/1.0.2/fail2ban_1.0.2-1.upstream1_all.deb - wget -O fail2ban.deb.asc https://github.com/fail2ban/fail2ban/releases/download/1.0.2/fail2ban_1.0.2-1.upstream1_all.deb.asc - dpkg -i fail2ban.deb ;; - centos|almalinux|rocky) - yum update -y && yum install epel-release -y - yum -y install fail2ban ;; - fedora) - dnf -y update && dnf -y install fail2ban ;; - *) - echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n" - exit 1 ;; + ubuntu | debian) + wget -O fail2ban.deb https://github.com/fail2ban/fail2ban/releases/download/1.0.2/fail2ban_1.0.2-1.upstream1_all.deb + wget -O fail2ban.deb.asc https://github.com/fail2ban/fail2ban/releases/download/1.0.2/fail2ban_1.0.2-1.upstream1_all.deb.asc + dpkg -i fail2ban.deb + ;; + centos | almalinux | rocky) + yum update -y && yum install epel-release -y + yum -y install fail2ban + ;; + fedora) + dnf -y update && dnf -y install fail2ban + ;; + *) + echo -e "${red}Unsupported operating system. Please check the script and install the necessary packages manually.${plain}\n" + exit 1 + ;; esac if ! command -v fail2ban-client &>/dev/null; then @@ -1041,45 +1057,53 @@ install_iplimit() { before_show_menu } -remove_iplimit(){ +remove_iplimit() { echo -e "${green}\t1.${plain} Only remove IP Limit configurations" echo -e "${green}\t2.${plain} Uninstall Fail2ban and IP Limit" echo -e "${green}\t0.${plain} Abort" read -p "Choose an option: " num case "$num" in - 1) - rm -f /etc/fail2ban/filter.d/3x-ipl.conf - rm -f /etc/fail2ban/action.d/3x-ipl.conf - rm -f /etc/fail2ban/jail.d/3x-ipl.conf - systemctl restart fail2ban - echo -e "${green}IP Limit removed successfully!${plain}\n" - before_show_menu ;; - 2) - rm -rf /etc/fail2ban - systemctl stop fail2ban - case "${release}" in - ubuntu|debian) - apt-get remove -y fail2ban - apt-get purge -y fail2ban -y - apt-get autoremove -y;; - centos|almalinux|rocky) - yum remove fail2ban -y - yum autoremove -y;; - fedora) - dnf remove fail2ban -y - dnf autoremove -y;; - *) - echo -e "${red}Unsupported operating system. Please uninstall Fail2ban manually.${plain}\n" - exit 1 ;; - esac - echo -e "${green}Fail2ban and IP Limit removed successfully!${plain}\n" - before_show_menu ;; - 0) - echo -e "${yellow}Cancelled.${plain}\n" - iplimit_main ;; - *) - echo -e "${red}Invalid option. Please select a valid number.${plain}\n" - remove_iplimit ;; + 1) + rm -f /etc/fail2ban/filter.d/3x-ipl.conf + rm -f /etc/fail2ban/action.d/3x-ipl.conf + rm -f /etc/fail2ban/jail.d/3x-ipl.conf + systemctl restart fail2ban + echo -e "${green}IP Limit removed successfully!${plain}\n" + before_show_menu + ;; + 2) + rm -rf /etc/fail2ban + systemctl stop fail2ban + case "${release}" in + ubuntu | debian) + apt-get remove -y fail2ban + apt-get purge -y fail2ban -y + apt-get autoremove -y + ;; + centos | almalinux | rocky) + yum remove fail2ban -y + yum autoremove -y + ;; + fedora) + dnf remove fail2ban -y + dnf autoremove -y + ;; + *) + echo -e "${red}Unsupported operating system. Please uninstall Fail2ban manually.${plain}\n" + exit 1 + ;; + esac + echo -e "${green}Fail2ban and IP Limit removed successfully!${plain}\n" + before_show_menu + ;; + 0) + echo -e "${yellow}Cancelled.${plain}\n" + iplimit_main + ;; + *) + echo -e "${red}Invalid option. Please select a valid number.${plain}\n" + remove_iplimit + ;; esac } @@ -1214,7 +1238,7 @@ show_menu() { ;; 24) run_speedtest - ;; + ;; *) LOGE "Please enter the correct number [0-24]" ;; From ebaabf61509a02090016acae886b2a7df216e814 Mon Sep 17 00:00:00 2001 From: quydang <81231812+quydang04@users.noreply.github.com> Date: Sat, 20 Jan 2024 23:41:58 +0700 Subject: [PATCH 5/9] Update README (#1648) --- README.md | 29 +++++++++++++++-------------- x-ui.sh | 4 ++-- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 60c6c044..6b0beab7 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,22 @@ update to latest version - AlmaLinux 9+ - Rockylinux 9+ +## Compatible Architectures & Devices +Supports a variety of different architectures and devices. Here are some of the main architectures that we support: + +- **amd64**: This is the most common architecture for personal computers and servers. It supports most modern operating systems. + +- **x86 / i386**: This architecture is prevalent in desktop and laptop computers. It's widely supported by various operating systems and applications. (Ex: Most Windows, macOS, and Linux systems) + +- **armv8 / arm64 / aarch64**: This is the architecture for modern mobile and embedded devices, including smartphones and tablets. (Ex: Raspberry Pi 4, Raspberry Pi 3, Raspberry Pi Zero 2/Zero 2 W, Orange Pi 3 LTS,...) + +- **armv7 / arm / arm32**: This is the architecture for older mobile and embedded devices. It is still widely used in many devices. (Ex: Orange Pi Zero LTS, Orange Pi PC Plus, Raspberry Pi 2,...) + +- **armv6 / arm / arm32**: This is the architecture for very old embedded devices. While not as common as before, there are still some devices using this architecture. (Ex: Raspberry Pi 1, Raspberry Pi Zero/Zero W,...) + +- **armv5 / arm / arm32**: This is an older architecture primarily used in early embedded systems. While it's less common today, some legacy devices may still rely on this architecture. (Ex: Early versions of Raspberry Pi, some older smartphones) + ## Languages - English @@ -398,20 +413,6 @@ XUI_BIN_FOLDER="bin" XUI_DB_FOLDER="/etc/x-ui" go build main.go - -## Supported Architectures and Devices - -Supports a variety of different architectures and devices. Here are some of the main architectures that we support: - -- **amd64**: This is the most common architecture for personal computers and servers. It supports most modern operating systems. - -- **armv8 / arm64 / aarch64**: This is the architecture for modern mobile and embedded devices, including smartphones and tablets. (Ex: Raspberry Pi 4, Raspberry Pi 3, Raspberry Pi Zero 2/Zero 2 W, Orange Pi 3 LTS,...) - -- **armv7 / arm / arm32**: This is the architecture for older mobile and embedded devices. It is still widely used in many devices. (Ex: Orange Pi Zero LTS, Orange Pi PC Plus, Raspberry Pi 2,...) - -- **armv6 / arm / arm32**: This is the architecture for very old embedded devices. While not as common as before, there are still some devices using this architecture. (Ex: Raspberry Pi 1, Raspberry Pi Zero/Zero W,...) - - ## Preview ![1](./media/1.png) diff --git a/x-ui.sh b/x-ui.sh index cabb546f..9fa43960 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -872,7 +872,7 @@ create_iplimit_jails() { # Use default bantime if not passed => 30 minutes local bantime="${1:-30}" - # uncomment allowipv6 = auto in fail2ban.conf + # Uncomment 'allowipv6 = auto' in fail2ban.conf sed -i 's/#allowipv6 = auto/allowipv6 = auto/g' /etc/fail2ban/fail2ban.conf cat << EOF > /etc/fail2ban/jail.d/3x-ipl.conf @@ -917,7 +917,7 @@ actionunban = -D f2b- -s -j [Init] EOF - echo -e "${green}Created Ip Limit jail files with a bantime of ${bantime} minutes.${plain}" + echo -e "${green}Ip Limit jail files created with a bantime of ${bantime} minutes.${plain}" } iplimit_remove_conflicts() { From 820e302aac04312f8353b1bc839e39be70518441 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Sun, 21 Jan 2024 04:00:58 +0330 Subject: [PATCH 6/9] revert fail2ban v1.0.2 it doesn't work well --- x-ui.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/x-ui.sh b/x-ui.sh index 9fa43960..20336c18 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -998,9 +998,7 @@ install_iplimit() { # Check the OS and install necessary packages case "${release}" in ubuntu | debian) - wget -O fail2ban.deb https://github.com/fail2ban/fail2ban/releases/download/1.0.2/fail2ban_1.0.2-1.upstream1_all.deb - wget -O fail2ban.deb.asc https://github.com/fail2ban/fail2ban/releases/download/1.0.2/fail2ban_1.0.2-1.upstream1_all.deb.asc - dpkg -i fail2ban.deb + apt update && apt install fail2ban -y ;; centos | almalinux | rocky) yum update -y && yum install epel-release -y From 4b9bbbc34b3ed5563f9cb14420b768d241580cf3 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Sun, 21 Jan 2024 04:45:17 +0330 Subject: [PATCH 7/9] clear banned log after unban everyone --- x-ui.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/x-ui.sh b/x-ui.sh index 20336c18..c7331e6d 100644 --- a/x-ui.sh +++ b/x-ui.sh @@ -970,6 +970,7 @@ iplimit_main() { confirm "Proceed with Unbanning everyone from IP Limit jail?" "y" if [[ $? == 0 ]]; then fail2ban-client reload --restart --unban 3x-ipl + truncate -s 0 "${iplimit_banned_log_path}" echo -e "${green}All users Unbanned successfully.${plain}" iplimit_main else From e7ce8c8ddb8472695b296eac305c5ac9b8c1d3d8 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Sun, 21 Jan 2024 14:39:15 +0330 Subject: [PATCH 8/9] minor changes disAllowedIps doesn't show on debug if there is no ip change copy to clipboard to export inbound --- go.mod | 2 +- go.sum | 4 ++-- web/html/xui/inbounds.html | 2 +- web/job/check_client_ip_job.go | 23 ++++++++++++++--------- web/translation/translate.en_US.toml | 2 +- web/translation/translate.es_ES.toml | 2 +- web/translation/translate.fa_IR.toml | 2 +- web/translation/translate.ru_RU.toml | 2 +- web/translation/translate.vi_VN.toml | 2 +- web/translation/translate.zh_Hans.toml | 2 +- 10 files changed, 24 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 6a116ba3..4e84c3e2 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.16.0 // indirect + github.com/go-playground/validator/v10 v10.17.0 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/btree v1.1.2 // indirect diff --git a/go.sum b/go.sum index 0b593906..f5d3b46b 100644 --- a/go.sum +++ b/go.sum @@ -76,8 +76,8 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE= -github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.17.0 h1:SmVVlfAOtlZncTxRuinDPomC2DkXJ4E5T9gDA0AIH74= +github.com/go-playground/validator/v10 v10.17.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= diff --git a/web/html/xui/inbounds.html b/web/html/xui/inbounds.html index 79326ca2..c986e3fd 100644 --- a/web/html/xui/inbounds.html +++ b/web/html/xui/inbounds.html @@ -230,7 +230,7 @@ - {{ i18n "pages.inbounds.copyToClipboard" }} + {{ i18n "pages.inbounds.exportInbound" }} {{ i18n "pages.inbounds.resetTraffic" }} diff --git a/web/job/check_client_ip_job.go b/web/job/check_client_ip_job.go index 65257170..b393e68d 100644 --- a/web/job/check_client_ip_job.go +++ b/web/job/check_client_ip_job.go @@ -16,17 +16,18 @@ import ( "x-ui/xray" ) -type CheckClientIpJob struct{} +type CheckClientIpJob struct { + disAllowedIps []string +} var job *CheckClientIpJob -var disAllowedIps []string var ipFiles = []string{ xray.GetIPLimitLogPath(), -xray.GetIPLimitPrevLogPath(), + xray.GetIPLimitPrevLogPath(), xray.GetIPLimitBannedLogPath(), -xray.GetIPLimitBannedPrevLogPath(), + xray.GetIPLimitBannedPrevLogPath(), xray.GetAccessPersistentLogPath(), -xray.GetAccessPersistentPrevLogPath(), + xray.GetAccessPersistentPrevLogPath(), } func NewCheckClientIpJob() *CheckClientIpJob { @@ -130,7 +131,6 @@ func (j *CheckClientIpJob) processLogFile() { } } - disAllowedIps = []string{} shouldCleanLog := false for clientEmail, ips := range InboundClientIps { @@ -237,6 +237,7 @@ func (j *CheckClientIpJob) updateInboundClientIps(inboundClientIps *model.Inboun json.Unmarshal([]byte(inbound.Settings), &settings) clients := settings["clients"] shouldCleanLog := false + j.disAllowedIps = []string{} // create iplimit log file channel logIpFile, err := os.OpenFile(xray.GetIPLimitLogPath(), os.O_CREATE|os.O_APPEND|os.O_RDWR, 0644) @@ -255,7 +256,7 @@ func (j *CheckClientIpJob) updateInboundClientIps(inboundClientIps *model.Inboun shouldCleanLog = true if limitIp < len(ips) && inbound.Enable { - disAllowedIps = append(disAllowedIps, ips[limitIp:]...) + j.disAllowedIps = append(j.disAllowedIps, ips[limitIp:]...) for i := limitIp; i < len(ips); i++ { log.Printf("[LIMIT_IP] Email = %s || SRC = %s", clientEmail, ips[i]) } @@ -263,8 +264,12 @@ func (j *CheckClientIpJob) updateInboundClientIps(inboundClientIps *model.Inboun } } } - logger.Debug("disAllowedIps ", disAllowedIps) - sort.Strings(disAllowedIps) + + sort.Strings(j.disAllowedIps) + + if len(j.disAllowedIps) > 0 { + logger.Debug("disAllowedIps ", j.disAllowedIps) + } db := database.GetDB() err = db.Save(inboundClientIps).Error diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml index 2f1c0544..006378ab 100644 --- a/web/translation/translate.en_US.toml +++ b/web/translation/translate.en_US.toml @@ -178,7 +178,7 @@ "info" = "Info" "same" = "Same" "inboundData" = "Inbound's Data" -"copyToClipboard" = "Copy to Clipboard" +"exportInbound" = "Export Inbound" "import" = "Import" "importInbound" = "Import an Inbound" diff --git a/web/translation/translate.es_ES.toml b/web/translation/translate.es_ES.toml index 42a3a2b2..bbf50b6c 100644 --- a/web/translation/translate.es_ES.toml +++ b/web/translation/translate.es_ES.toml @@ -178,7 +178,7 @@ "info" = "Info" "same" = "misma" "inboundData" = "Datos de entrada" -"copyToClipboard" = "Copiar al portapapeles" +"exportInbound" = "Exportación entrante" "import" = "Importar" "importInbound" = "Importar un entrante" diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml index 3edcb4cb..1de8538c 100644 --- a/web/translation/translate.fa_IR.toml +++ b/web/translation/translate.fa_IR.toml @@ -178,7 +178,7 @@ "info" = "اطلاعات" "same" = "همسان" "inboundData" = "داده‌های ورودی" -"copyToClipboard" = "کپی در حافظه" +"exportInbound" = "استخراج ورودی" "import" = "افزودن" "importInbound" = "افزودن یک ورودی" diff --git a/web/translation/translate.ru_RU.toml b/web/translation/translate.ru_RU.toml index d8211d8d..2f33311e 100644 --- a/web/translation/translate.ru_RU.toml +++ b/web/translation/translate.ru_RU.toml @@ -178,7 +178,7 @@ "info" = "Информация" "same" = "Тот же" "inboundData" = "Входящие данные" -"copyToClipboard" = "Копировать в буфер обмена" +"exportInbound" = "Экспорт входящих" "import" = "Импортировать" "importInbound" = "Импортировать входящее сообщение" diff --git a/web/translation/translate.vi_VN.toml b/web/translation/translate.vi_VN.toml index 7491a70c..1a2cfaa0 100644 --- a/web/translation/translate.vi_VN.toml +++ b/web/translation/translate.vi_VN.toml @@ -178,7 +178,7 @@ "info" = "Thông tin" "same" = "Giống nhau" "inboundData" = "Dữ liệu gửi đến" -"copyToClipboard" = "Sao chép vào bảng nhớ tạm" +"exportInbound" = "Xuất nhập khẩu" "import" = "Nhập" "importInbound" = "Nhập inbound" diff --git a/web/translation/translate.zh_Hans.toml b/web/translation/translate.zh_Hans.toml index 5a46ec73..966ef3f7 100644 --- a/web/translation/translate.zh_Hans.toml +++ b/web/translation/translate.zh_Hans.toml @@ -178,7 +178,7 @@ "info" = "信息" "same" = "相同" "inboundData" = "入站数据" -"copyToClipboard" = "复制到剪贴板" +"exportInbound" = "出口 入境" "import"="导入" "importInbound" = "导入入站" From 5c695ca6520c9cd9c44b18119a862f8f480969af Mon Sep 17 00:00:00 2001 From: Ali Rahimi Date: Sun, 21 Jan 2024 15:26:19 +0100 Subject: [PATCH 9/9] add group user with the same subscription id to all inbounds (#1650) --- web/assets/js/util/utils.js | 35 +++++++++++ web/controller/inbound.go | 39 +++++++------ web/html/common/qrcode_modal.html | 17 ++++-- web/html/xui/client_modal.html | 80 +++++++++++++++++++++----- web/html/xui/form/client.html | 4 +- web/html/xui/inbound_modal.html | 4 ++ web/html/xui/inbounds.html | 59 +++++++++++++++---- web/translation/translate.en_US.toml | 1 + web/translation/translate.es_ES.toml | 1 + web/translation/translate.fa_IR.toml | 1 + web/translation/translate.ru_RU.toml | 1 + web/translation/translate.vi_VN.toml | 1 + web/translation/translate.zh_Hans.toml | 1 + 13 files changed, 196 insertions(+), 48 deletions(-) diff --git a/web/assets/js/util/utils.js b/web/assets/js/util/utils.js index 61b322bd..48ff237d 100644 --- a/web/assets/js/util/utils.js +++ b/web/assets/js/util/utils.js @@ -83,6 +83,41 @@ class HttpUtil { } return msg; } + + static async jsonPost(url, data) { + let msg; + try { + const requestOptions = { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(data), + }; + const resp = await fetch(url, requestOptions); + const response = await resp.json(); + + msg = this._respToMsg({data : response}); + } catch (e) { + msg = new Msg(false, e.toString()); + } + this._handleMsg(msg); + return msg; + } + + static async postWithModalJson(url, data, modal) { + if (modal) { + modal.loading(true); + } + const msg = await this.jsonPost(url, data); + if (modal) { + modal.loading(false); + if (msg instanceof Msg && msg.success) { + modal.close(); + } + } + return msg; + } } class PromiseUtil { diff --git a/web/controller/inbound.go b/web/controller/inbound.go index 86da9813..b274be64 100644 --- a/web/controller/inbound.go +++ b/web/controller/inbound.go @@ -159,24 +159,31 @@ func (a *InboundController) clearClientIps(c *gin.Context) { } func (a *InboundController) addInboundClient(c *gin.Context) { - data := &model.Inbound{} - err := c.ShouldBind(data) - if err != nil { - jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err) - return - } + var requestData []model.Inbound - needRestart := true + err := c.ShouldBindJSON(&requestData) + + if err != nil { + jsonMsg(c, I18nWeb(c, "pages.inbounds.update"), err) + return + } + + needRestart := true + + for _, data := range requestData { + + needRestart, err = a.inboundService.AddInboundClient(&data) + if err != nil { + jsonMsg(c, "Something went wrong!", err) + return + } + } + + jsonMsg(c, "Client(s) added", nil) + if err == nil && needRestart { + a.xrayService.SetToNeedRestart() + } - needRestart, err = a.inboundService.AddInboundClient(data) - if err != nil { - jsonMsg(c, "Something went wrong!", err) - return - } - jsonMsg(c, "Client(s) added", nil) - if err == nil && needRestart { - a.xrayService.SetToNeedRestart() - } } func (a *InboundController) delInboundClient(c *gin.Context) { diff --git a/web/html/common/qrcode_modal.html b/web/html/common/qrcode_modal.html index 3c4fd929..31b3450c 100644 --- a/web/html/common/qrcode_modal.html +++ b/web/html/common/qrcode_modal.html @@ -11,10 +11,12 @@ Subscription
- {{ i18n "pages.inbounds.client" }} - - + + @@ -373,7 +377,7 @@

[[ clientEmail ]]

[[ clientCount[dbInbound.id].online.length ]] - + @@ -740,6 +744,9 @@ case "delDepletedClients": this.delDepletedClients(-1) break; + case "addGroupClient": + this.openGroupAddClient() + break; } }, clickAction(action, dbInbound) { @@ -883,6 +890,20 @@ await this.submit(`/panel/inbound/update/${dbInbound.id}`, data, inModal); }, + openGroupAddClient() { + clientModal.show({ + title: '{{ i18n "pages.client.groupAdd"}}', + okText: '{{ i18n "pages.client.submitAdd"}}', + dbInbound: this.dbInbounds, + confirm: async (clients, dbInboundIds) => { + clientModal.loading(); + await this.addGroupClient(clients, dbInboundIds); + clientModal.close(); + await this.showQrcode(dbInboundIds[0],clients[0], true) + }, + isEdit: false + }); + }, openAddClient(dbInboundId) { dbInbound = this.dbInbounds.find(row => row.id === dbInboundId); clientModal.show({ @@ -893,6 +914,7 @@ clientModal.loading(); await this.addClient(clients, dbInboundId); clientModal.close(); + await this.showQrcode(dbInboundId,clients) }, isEdit: false }); @@ -936,11 +958,24 @@ } }, async addClient(clients, dbInboundId) { - const data = { + const data = [{ id: dbInboundId, settings: '{"clients": [' + clients.toString() + ']}', - }; - await this.submit(`/panel/inbound/addClient`, data); + }]; + + await this.submit(`/panel/inbound/addClient`, data, true) + }, + + async addGroupClient(clients, dbInboundIds) { + const data = [] + dbInboundIds.forEach((dbInboundId, index) => { + data.push({ + id: dbInboundId, + settings: '{"clients": [' + clients[index].toString() + ']}', + }) + }) + + await this.submit(`/panel/inbound/addClient`, data, true) }, async updateClient(client, dbInboundId, clientId) { const data = { @@ -1001,8 +1036,8 @@ checkFallback(dbInbound) { newDbInbound = new DBInbound(dbInbound); if (dbInbound.listen.startsWith("@")){ - rootInbound = this.inbounds.find((i) => - i.isTcp && + rootInbound = this.inbounds.find((i) => + i.isTcp && ['trojan','vless'].includes(i.protocol) && i.settings.fallbacks.find(f => f.dest === dbInbound.listen) ); @@ -1018,10 +1053,10 @@ } return newDbInbound; }, - showQrcode(dbInboundId, client) { + showQrcode(dbInboundId, client, isJustSub = false) { dbInbound = this.dbInbounds.find(row => row.id === dbInboundId); newDbInbound = this.checkFallback(dbInbound); - qrModal.show('{{ i18n "qrCode"}}', newDbInbound, client); + qrModal.show('{{ i18n "qrCode"}}', newDbInbound, client, isJustSub); }, showInfo(dbInboundId, client) { dbInbound = this.dbInbounds.find(row => row.id === dbInboundId); @@ -1050,8 +1085,8 @@ await this.updateClient(clients[index], dbInboundId, clientId); this.loading(false); }, - async submit(url, data) { - const msg = await HttpUtil.postWithModal(url, data); + async submit(url, data, isJson = false) { + const msg = isJson ? await HttpUtil.postWithModalJson(url, data) : await HttpUtil.postWithModal(url, data); if (msg.success) { await this.getDBInbounds(); } diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml index 006378ab..b2d74c3b 100644 --- a/web/translation/translate.en_US.toml +++ b/web/translation/translate.en_US.toml @@ -184,6 +184,7 @@ [pages.client] "add" = "Add Client" +"groupAdd" = "Add subscription user" "edit" = "Edit Client" "submitAdd" = "Add Client" "submitEdit" = "Save Changes" diff --git a/web/translation/translate.es_ES.toml b/web/translation/translate.es_ES.toml index bbf50b6c..83c9460b 100644 --- a/web/translation/translate.es_ES.toml +++ b/web/translation/translate.es_ES.toml @@ -184,6 +184,7 @@ [pages.client] "add" = "Agregar Cliente" +"groupAdd" = "Agregar usuario de suscripción" "edit" = "Editar Cliente" "submitAdd" = "Agregar Cliente" "submitEdit" = "Guardar Cambios" diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml index 1de8538c..9613c12e 100644 --- a/web/translation/translate.fa_IR.toml +++ b/web/translation/translate.fa_IR.toml @@ -184,6 +184,7 @@ [pages.client] "add" = "کاربر جدید" +"groupAdd" = "کاربر جدید سابسکریپشن" "edit" = "ویرایش کاربر" "submitAdd" = "اضافه کردن" "submitEdit" = "ذخیره تغییرات" diff --git a/web/translation/translate.ru_RU.toml b/web/translation/translate.ru_RU.toml index 2f33311e..7cf2be0a 100644 --- a/web/translation/translate.ru_RU.toml +++ b/web/translation/translate.ru_RU.toml @@ -184,6 +184,7 @@ [pages.client] "add" = "Добавить пользователя" +"groupAdd" = "Добавить пользователя подписки" "edit" = "Редактировать пользователя" "submitAdd" = "Добавить пользователя" "submitEdit" = "Сохранить изменения" diff --git a/web/translation/translate.vi_VN.toml b/web/translation/translate.vi_VN.toml index 1a2cfaa0..9cd7bc46 100644 --- a/web/translation/translate.vi_VN.toml +++ b/web/translation/translate.vi_VN.toml @@ -184,6 +184,7 @@ [pages.client] "add" = "Thêm người dùng" +"groupAdd" = "Thêm người dùng đăng ký" "edit" = "Chỉnh sửa người dùng" "submitAdd" = "Thêm" "submitEdit" = "Lưu thay đổi" diff --git a/web/translation/translate.zh_Hans.toml b/web/translation/translate.zh_Hans.toml index 966ef3f7..c229dc29 100644 --- a/web/translation/translate.zh_Hans.toml +++ b/web/translation/translate.zh_Hans.toml @@ -184,6 +184,7 @@ [pages.client] "add" = "添加客户端" +"groupAdd" = "添加订阅用户" "edit" = "编辑客户端" "submitAdd" = "添加客户端" "submitEdit" = "保存修改"