Compare commits
10 Commits
21058eb63c
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| d186cd9a32 | |||
| eacb9f63b0 | |||
| e7035b56fe | |||
| 5f526e5201 | |||
| bd8d33980f | |||
| 5dc02a9af3 | |||
| 033c5993e0 | |||
| 2204c8231d | |||
| 01a7dc807b | |||
| 6bf4a2c4f0 |
@@ -72,7 +72,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
- uses: actions/setup-node@v5
|
- uses: actions/setup-node@v6
|
||||||
with:
|
with:
|
||||||
node-version-file: .nvmrc
|
node-version-file: .nvmrc
|
||||||
cache: npm
|
cache: npm
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@
|
|||||||
## البدء السريع
|
## البدء السريع
|
||||||
|
|
||||||
```
|
```
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/install.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
للحصول على الوثائق الكاملة، يرجى زيارة [ويكي المشروع](https://github.com/MHSanaei/3x-ui/wiki).
|
للحصول على الوثائق الكاملة، يرجى زيارة [ويكي المشروع](https://github.com/MHSanaei/3x-ui/wiki).
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ Como una versión mejorada del proyecto X-UI original, 3X-UI proporciona mayor e
|
|||||||
## Inicio Rápido
|
## Inicio Rápido
|
||||||
|
|
||||||
```
|
```
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/install.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
Para documentación completa, visita la [Wiki del proyecto](https://github.com/MHSanaei/3x-ui/wiki).
|
Para documentación completa, visita la [Wiki del proyecto](https://github.com/MHSanaei/3x-ui/wiki).
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@
|
|||||||
## شروع سریع
|
## شروع سریع
|
||||||
|
|
||||||
```
|
```
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/install.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
برای مستندات کامل، لطفاً به [ویکی پروژه](https://github.com/MHSanaei/3x-ui/wiki) مراجعه کنید.
|
برای مستندات کامل، لطفاً به [ویکی پروژه](https://github.com/MHSanaei/3x-ui/wiki) مراجعه کنید.
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ As an enhanced fork of the original X-UI project, 3X-UI provides improved stabil
|
|||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/install.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
For full documentation, please visit the [project Wiki](https://github.com/MHSanaei/3x-ui/wiki).
|
For full documentation, please visit the [project Wiki](https://github.com/MHSanaei/3x-ui/wiki).
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@
|
|||||||
## Быстрый старт
|
## Быстрый старт
|
||||||
|
|
||||||
```
|
```
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/install.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
Полную документацию смотрите в [вики проекта](https://github.com/MHSanaei/3x-ui/wiki).
|
Полную документацию смотрите в [вики проекта](https://github.com/MHSanaei/3x-ui/wiki).
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@
|
|||||||
## 快速开始
|
## 快速开始
|
||||||
|
|
||||||
```
|
```
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
bash <(curl -Ls https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/install.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
完整文档请参阅 [项目Wiki](https://github.com/MHSanaei/3x-ui/wiki)。
|
完整文档请参阅 [项目Wiki](https://github.com/MHSanaei/3x-ui/wiki)。
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
3.0.1
|
3.0.2
|
||||||
+28
-2
@@ -10,6 +10,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"slices"
|
"slices"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/mhsanaei/3x-ui/v3/config"
|
"github.com/mhsanaei/3x-ui/v3/config"
|
||||||
@@ -42,8 +43,12 @@ func initModels() error {
|
|||||||
&model.Node{},
|
&model.Node{},
|
||||||
&model.ApiToken{},
|
&model.ApiToken{},
|
||||||
}
|
}
|
||||||
for _, model := range models {
|
for _, mdl := range models {
|
||||||
if err := db.AutoMigrate(model); err != nil {
|
if err := db.AutoMigrate(mdl); err != nil {
|
||||||
|
if isIgnorableDuplicateColumnErr(err, mdl) {
|
||||||
|
log.Printf("Ignoring duplicate column during auto migration for %T: %v", mdl, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
log.Printf("Error auto migrating model: %v", err)
|
log.Printf("Error auto migrating model: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -51,6 +56,27 @@ func initModels() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isIgnorableDuplicateColumnErr(err error, mdl any) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
errMsg := strings.ToLower(err.Error())
|
||||||
|
const dupPrefix = "duplicate column name:"
|
||||||
|
if !strings.Contains(errMsg, dupPrefix) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
idx := strings.Index(errMsg, dupPrefix)
|
||||||
|
if idx < 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
col := strings.TrimSpace(errMsg[idx+len(dupPrefix):])
|
||||||
|
col = strings.Trim(col, "`\"[]")
|
||||||
|
if col == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return db != nil && db.Migrator().HasColumn(mdl, col)
|
||||||
|
}
|
||||||
|
|
||||||
// initUser creates a default admin user if the users table is empty.
|
// initUser creates a default admin user if the users table is empty.
|
||||||
func initUser() error {
|
func initUser() error {
|
||||||
empty, err := isTableEmpty("users")
|
empty, err := isTableEmpty("users")
|
||||||
|
|||||||
+2
-1
@@ -12,5 +12,6 @@ services:
|
|||||||
XRAY_VMESS_AEAD_FORCED: "false"
|
XRAY_VMESS_AEAD_FORCED: "false"
|
||||||
XUI_ENABLE_FAIL2BAN: "true"
|
XUI_ENABLE_FAIL2BAN: "true"
|
||||||
tty: true
|
tty: true
|
||||||
network_mode: host
|
ports:
|
||||||
|
- "2053:2053"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "3x-ui-frontend",
|
"name": "3x-ui-frontend",
|
||||||
"version": "0.0.2",
|
"version": "0.0.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "3x-ui-frontend",
|
"name": "3x-ui-frontend",
|
||||||
"version": "0.0.2",
|
"version": "0.0.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons-vue": "^7.0.1",
|
"@ant-design/icons-vue": "^7.0.1",
|
||||||
"@codemirror/lang-json": "^6.0.2",
|
"@codemirror/lang-json": "^6.0.2",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "3x-ui-frontend",
|
"name": "3x-ui-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.2",
|
"version": "0.0.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "3x-ui panel frontend (Vue 3 + Ant Design Vue 4 + Vite 8).",
|
"description": "3x-ui panel frontend (Vue 3 + Ant Design Vue 4 + Vite 8).",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -40,4 +40,4 @@
|
|||||||
"overrides": {
|
"overrides": {
|
||||||
"moment-jalaali": "^0.10.4"
|
"moment-jalaali": "^0.10.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1595,6 +1595,10 @@ export class Inbound extends XrayCommonClass {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof xhttp.mode === 'string' && xhttp.mode.length > 0) {
|
||||||
|
extra.mode = xhttp.mode;
|
||||||
|
}
|
||||||
|
|
||||||
const stringFields = [
|
const stringFields = [
|
||||||
"sessionPlacement", "sessionKey",
|
"sessionPlacement", "sessionKey",
|
||||||
"seqPlacement", "seqKey",
|
"seqPlacement", "seqKey",
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ const savedFilterState = (() => {
|
|||||||
const enableFilter = ref(!!savedFilterState.enableFilter);
|
const enableFilter = ref(!!savedFilterState.enableFilter);
|
||||||
const searchKey = ref(savedFilterState.searchKey || '');
|
const searchKey = ref(savedFilterState.searchKey || '');
|
||||||
const filterBy = ref(savedFilterState.filterBy || '');
|
const filterBy = ref(savedFilterState.filterBy || '');
|
||||||
const protocolFilter = ref(savedFilterState.protocolFilter || '');
|
const protocolFilter = ref(savedFilterState.protocolFilter || undefined);
|
||||||
const nodeFilter = ref(savedFilterState.nodeFilter || '');
|
const nodeFilter = ref(savedFilterState.nodeFilter || '');
|
||||||
|
|
||||||
watch([enableFilter, searchKey, filterBy, protocolFilter, nodeFilter], () => {
|
watch([enableFilter, searchKey, filterBy, protocolFilter, nodeFilter], () => {
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ watch(() => props.open, (next) => {
|
|||||||
}
|
}
|
||||||
const open = [];
|
const open = [];
|
||||||
if (subLink.value) open.push('sub');
|
if (subLink.value) open.push('sub');
|
||||||
if (subJsonLink.value) open.push('sub-json');
|
|
||||||
activeKeys.value = open;
|
activeKeys.value = open;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const props = defineProps({
|
|||||||
value: { type: String, required: true },
|
value: { type: String, required: true },
|
||||||
remark: { type: String, default: '' },
|
remark: { type: String, default: '' },
|
||||||
downloadName: { type: String, default: '' },
|
downloadName: { type: String, default: '' },
|
||||||
size: { type: Number, default: 240 },
|
size: { type: Number, default: 360 },
|
||||||
showQr: { type: Boolean, default: true },
|
showQr: { type: Boolean, default: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -82,8 +82,15 @@ function download() {
|
|||||||
|
|
||||||
.qr-panel-canvas .qr-code {
|
.qr-panel-canvas .qr-code {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 0 !important;
|
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qr-panel-canvas .qr-code :deep(svg) {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
max-width: 360px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -195,6 +195,7 @@ function convertLink() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
outbound.value = next;
|
outbound.value = next;
|
||||||
|
primeAdvancedJson();
|
||||||
linkInput.value = '';
|
linkInput.value = '';
|
||||||
message.success('Link imported successfully...');
|
message.success('Link imported successfully...');
|
||||||
activeKey.value = '1';
|
activeKey.value = '1';
|
||||||
|
|||||||
+13
-9
@@ -763,6 +763,9 @@ config_after_install() {
|
|||||||
|
|
||||||
prompt_and_setup_ssl "${config_port}" "${config_webBasePath}" "${server_ip}"
|
prompt_and_setup_ssl "${config_port}" "${config_webBasePath}" "${server_ip}"
|
||||||
|
|
||||||
|
# Retrieve the API token for display
|
||||||
|
local config_apiToken=$(${xui_folder}/x-ui setting -getApiToken true | grep -Eo 'apiToken: .+' | awk '{print $2}')
|
||||||
|
|
||||||
# Display final credentials and access information
|
# Display final credentials and access information
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${green}═══════════════════════════════════════════${plain}"
|
echo -e "${green}═══════════════════════════════════════════${plain}"
|
||||||
@@ -773,6 +776,7 @@ config_after_install() {
|
|||||||
echo -e "${green}Port: ${config_port}${plain}"
|
echo -e "${green}Port: ${config_port}${plain}"
|
||||||
echo -e "${green}WebBasePath: ${config_webBasePath}${plain}"
|
echo -e "${green}WebBasePath: ${config_webBasePath}${plain}"
|
||||||
echo -e "${green}Access URL: ${SSL_SCHEME}://${SSL_HOST}:${config_port}/${config_webBasePath}${plain}"
|
echo -e "${green}Access URL: ${SSL_SCHEME}://${SSL_HOST}:${config_port}/${config_webBasePath}${plain}"
|
||||||
|
echo -e "${green}API Token: ${config_apiToken}${plain}"
|
||||||
echo -e "${green}═══════════════════════════════════════════${plain}"
|
echo -e "${green}═══════════════════════════════════════════${plain}"
|
||||||
echo -e "${yellow}⚠ IMPORTANT: Save these credentials securely!${plain}"
|
echo -e "${yellow}⚠ IMPORTANT: Save these credentials securely!${plain}"
|
||||||
if [[ "$SSL_SCHEME" == "https" ]]; then
|
if [[ "$SSL_SCHEME" == "https" ]]; then
|
||||||
@@ -842,17 +846,17 @@ install_x-ui() {
|
|||||||
|
|
||||||
# Download resources
|
# Download resources
|
||||||
if [ $# == 0 ]; then
|
if [ $# == 0 ]; then
|
||||||
tag_version=$(curl -Ls "https://api.github.com/repos/MHSanaei/3x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
tag_version=$(curl -Ls "https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||||
if [[ ! -n "$tag_version" ]]; then
|
if [[ ! -n "$tag_version" ]]; then
|
||||||
echo -e "${yellow}Trying to fetch version with IPv4...${plain}"
|
echo -e "${yellow}Trying to fetch version with IPv4...${plain}"
|
||||||
tag_version=$(curl -4 -Ls "https://api.github.com/repos/MHSanaei/3x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
tag_version=$(curl -4 -Ls "https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||||
if [[ ! -n "$tag_version" ]]; then
|
if [[ ! -n "$tag_version" ]]; then
|
||||||
echo -e "${red}Failed to fetch x-ui version, it may be due to GitHub API restrictions, please try it later${plain}"
|
echo -e "${red}Failed to fetch x-ui version, it may be due to GitHub API restrictions, please try it later${plain}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
echo -e "Got x-ui latest version: ${tag_version}, beginning the installation..."
|
echo -e "Got x-ui latest version: ${tag_version}, beginning the installation..."
|
||||||
curl -4fLRo ${xui_folder}-linux-$(arch).tar.gz https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz
|
curl -4fLRo ${xui_folder}-linux-$(arch).tar.gz https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
echo -e "${red}Downloading x-ui failed, please be sure that your server can access GitHub ${plain}"
|
echo -e "${red}Downloading x-ui failed, please be sure that your server can access GitHub ${plain}"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -867,7 +871,7 @@ install_x-ui() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
url="https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz"
|
url="https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz"
|
||||||
echo -e "Beginning to install x-ui $1"
|
echo -e "Beginning to install x-ui $1"
|
||||||
curl -4fLRo ${xui_folder}-linux-$(arch).tar.gz ${url}
|
curl -4fLRo ${xui_folder}-linux-$(arch).tar.gz ${url}
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
@@ -875,7 +879,7 @@ install_x-ui() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
curl -4fLRo /usr/bin/x-ui-temp https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.sh
|
curl -4fLRo /usr/bin/x-ui-temp https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/x-ui.sh
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
echo -e "${red}Failed to download x-ui.sh${plain}"
|
echo -e "${red}Failed to download x-ui.sh${plain}"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -927,7 +931,7 @@ install_x-ui() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $release == "alpine" ]]; then
|
if [[ $release == "alpine" ]]; then
|
||||||
curl -4fLRo /etc/init.d/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.rc
|
curl -4fLRo /etc/init.d/x-ui https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/x-ui.rc
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
echo -e "${red}Failed to download x-ui.rc${plain}"
|
echo -e "${red}Failed to download x-ui.rc${plain}"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -984,13 +988,13 @@ install_x-ui() {
|
|||||||
echo -e "${yellow}Service files not found in tar.gz, downloading from GitHub...${plain}"
|
echo -e "${yellow}Service files not found in tar.gz, downloading from GitHub...${plain}"
|
||||||
case "${release}" in
|
case "${release}" in
|
||||||
ubuntu | debian | armbian)
|
ubuntu | debian | armbian)
|
||||||
curl -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.debian > /dev/null 2>&1
|
curl -4fLRo ${xui_service}/x-ui.service https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/x-ui.service.debian > /dev/null 2>&1
|
||||||
;;
|
;;
|
||||||
arch | manjaro | parch)
|
arch | manjaro | parch)
|
||||||
curl -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.arch > /dev/null 2>&1
|
curl -4fLRo ${xui_service}/x-ui.service https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/x-ui.service.arch > /dev/null 2>&1
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
curl -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.rhel > /dev/null 2>&1
|
curl -4fLRo ${xui_service}/x-ui.service https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/x-ui.service.rhel > /dev/null 2>&1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|||||||
@@ -391,6 +391,28 @@ func GetListenIP(getListen bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetApiToken(getApiToken bool) {
|
||||||
|
if !getApiToken {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
apiTokenService := service.ApiTokenService{}
|
||||||
|
tokens, err := apiTokenService.List()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("get apiToken failed, error info:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(tokens) > 0 {
|
||||||
|
fmt.Println("apiToken:", tokens[0].Token)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
created, err := apiTokenService.Create("install")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("create apiToken failed, error info:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("apiToken:", created.Token)
|
||||||
|
}
|
||||||
|
|
||||||
// migrateDb performs database migration operations for the 3x-ui panel.
|
// migrateDb performs database migration operations for the 3x-ui panel.
|
||||||
func migrateDb() {
|
func migrateDb() {
|
||||||
inboundService := service.InboundService{}
|
inboundService := service.InboundService{}
|
||||||
@@ -433,6 +455,7 @@ func main() {
|
|||||||
var reset bool
|
var reset bool
|
||||||
var show bool
|
var show bool
|
||||||
var getCert bool
|
var getCert bool
|
||||||
|
var getApiToken bool
|
||||||
var resetTwoFactor bool
|
var resetTwoFactor bool
|
||||||
settingCmd.BoolVar(&reset, "reset", false, "Reset all settings")
|
settingCmd.BoolVar(&reset, "reset", false, "Reset all settings")
|
||||||
settingCmd.BoolVar(&show, "show", false, "Display current settings")
|
settingCmd.BoolVar(&show, "show", false, "Display current settings")
|
||||||
@@ -444,6 +467,7 @@ func main() {
|
|||||||
settingCmd.BoolVar(&resetTwoFactor, "resetTwoFactor", false, "Reset two-factor authentication settings")
|
settingCmd.BoolVar(&resetTwoFactor, "resetTwoFactor", false, "Reset two-factor authentication settings")
|
||||||
settingCmd.BoolVar(&getListen, "getListen", false, "Display current panel listenIP IP")
|
settingCmd.BoolVar(&getListen, "getListen", false, "Display current panel listenIP IP")
|
||||||
settingCmd.BoolVar(&getCert, "getCert", false, "Display current certificate settings")
|
settingCmd.BoolVar(&getCert, "getCert", false, "Display current certificate settings")
|
||||||
|
settingCmd.BoolVar(&getApiToken, "getApiToken", false, "Display current API token")
|
||||||
settingCmd.StringVar(&webCertFile, "webCert", "", "Set path to public key file for panel")
|
settingCmd.StringVar(&webCertFile, "webCert", "", "Set path to public key file for panel")
|
||||||
settingCmd.StringVar(&webKeyFile, "webCertKey", "", "Set path to private key file for panel")
|
settingCmd.StringVar(&webKeyFile, "webCertKey", "", "Set path to private key file for panel")
|
||||||
settingCmd.StringVar(&tgbottoken, "tgbottoken", "", "Set token for Telegram bot")
|
settingCmd.StringVar(&tgbottoken, "tgbottoken", "", "Set token for Telegram bot")
|
||||||
@@ -501,6 +525,9 @@ func main() {
|
|||||||
if getCert {
|
if getCert {
|
||||||
GetCertificate(getCert)
|
GetCertificate(getCert)
|
||||||
}
|
}
|
||||||
|
if getApiToken {
|
||||||
|
GetApiToken(getApiToken)
|
||||||
|
}
|
||||||
if (tgbottoken != "") || (tgbotchatid != "") || (tgbotRuntime != "") {
|
if (tgbottoken != "") || (tgbotchatid != "") || (tgbotRuntime != "") {
|
||||||
updateTgbotSetting(tgbottoken, tgbotchatid, tgbotRuntime)
|
updateTgbotSetting(tgbottoken, tgbotchatid, tgbotRuntime)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -265,6 +265,14 @@ func (s *SubJsonService) streamData(stream string) map[string]any {
|
|||||||
streamSettings["wsSettings"] = s.removeAcceptProxy(streamSettings["wsSettings"])
|
streamSettings["wsSettings"] = s.removeAcceptProxy(streamSettings["wsSettings"])
|
||||||
case "httpupgrade":
|
case "httpupgrade":
|
||||||
streamSettings["httpupgradeSettings"] = s.removeAcceptProxy(streamSettings["httpupgradeSettings"])
|
streamSettings["httpupgradeSettings"] = s.removeAcceptProxy(streamSettings["httpupgradeSettings"])
|
||||||
|
case "xhttp":
|
||||||
|
streamSettings["xhttpSettings"] = s.removeAcceptProxy(streamSettings["xhttpSettings"])
|
||||||
|
if xhttp, ok := streamSettings["xhttpSettings"].(map[string]any); ok {
|
||||||
|
delete(xhttp, "noSSEHeader")
|
||||||
|
delete(xhttp, "scMaxBufferedPosts")
|
||||||
|
delete(xhttp, "scStreamUpServerSecs")
|
||||||
|
delete(xhttp, "serverMaxHeaderBytes")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return streamSettings
|
return streamSettings
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1025,6 +1025,10 @@ func buildXhttpExtra(xhttp map[string]any) map[string]any {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if mode, ok := xhttp["mode"].(string); ok && len(mode) > 0 {
|
||||||
|
extra["mode"] = mode
|
||||||
|
}
|
||||||
|
|
||||||
stringFields := []string{
|
stringFields := []string{
|
||||||
"sessionPlacement", "sessionKey",
|
"sessionPlacement", "sessionKey",
|
||||||
"seqPlacement", "seqKey",
|
"seqPlacement", "seqKey",
|
||||||
|
|||||||
@@ -784,19 +784,19 @@ update_x-ui() {
|
|||||||
|
|
||||||
echo -e "${green}Downloading new x-ui version...${plain}"
|
echo -e "${green}Downloading new x-ui version...${plain}"
|
||||||
|
|
||||||
tag_version=$(${curl_bin} -Ls "https://api.github.com/repos/MHSanaei/3x-ui/releases/latest" 2> /dev/null | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
tag_version=$(${curl_bin} -Ls "https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/releases/latest" 2> /dev/null | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||||
if [[ ! -n "$tag_version" ]]; then
|
if [[ ! -n "$tag_version" ]]; then
|
||||||
echo -e "${yellow}Trying to fetch version with IPv4...${plain}"
|
echo -e "${yellow}Trying to fetch version with IPv4...${plain}"
|
||||||
tag_version=$(${curl_bin} -4 -Ls "https://api.github.com/repos/MHSanaei/3x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
tag_version=$(${curl_bin} -4 -Ls "https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||||
if [[ ! -n "$tag_version" ]]; then
|
if [[ ! -n "$tag_version" ]]; then
|
||||||
_fail "ERROR: Failed to fetch x-ui version, it may be due to GitHub API restrictions, please try it later"
|
_fail "ERROR: Failed to fetch x-ui version, it may be due to GitHub API restrictions, please try it later"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
echo -e "Got x-ui latest version: ${tag_version}, beginning the installation..."
|
echo -e "Got x-ui latest version: ${tag_version}, beginning the installation..."
|
||||||
${curl_bin} -fLRo ${xui_folder}-linux-$(arch).tar.gz https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz 2> /dev/null
|
${curl_bin} -fLRo ${xui_folder}-linux-$(arch).tar.gz https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz 2> /dev/null
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
echo -e "${yellow}Trying to fetch version with IPv4...${plain}"
|
echo -e "${yellow}Trying to fetch version with IPv4...${plain}"
|
||||||
${curl_bin} -4fLRo ${xui_folder}-linux-$(arch).tar.gz https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz 2> /dev/null
|
${curl_bin} -4fLRo ${xui_folder}-linux-$(arch).tar.gz https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz 2> /dev/null
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
_fail "ERROR: Failed to download x-ui, please be sure that your server can access GitHub"
|
_fail "ERROR: Failed to download x-ui, please be sure that your server can access GitHub"
|
||||||
fi
|
fi
|
||||||
@@ -859,10 +859,10 @@ update_x-ui() {
|
|||||||
chmod +x x-ui bin/xray-linux-$(arch) > /dev/null 2>&1
|
chmod +x x-ui bin/xray-linux-$(arch) > /dev/null 2>&1
|
||||||
|
|
||||||
echo -e "${green}Downloading and installing x-ui.sh script...${plain}"
|
echo -e "${green}Downloading and installing x-ui.sh script...${plain}"
|
||||||
${curl_bin} -fLRo /usr/bin/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.sh > /dev/null 2>&1
|
${curl_bin} -fLRo /usr/bin/x-ui https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/x-ui.sh > /dev/null 2>&1
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
echo -e "${yellow}Trying to fetch x-ui with IPv4...${plain}"
|
echo -e "${yellow}Trying to fetch x-ui with IPv4...${plain}"
|
||||||
${curl_bin} -4fLRo /usr/bin/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.sh > /dev/null 2>&1
|
${curl_bin} -4fLRo /usr/bin/x-ui https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/x-ui.sh > /dev/null 2>&1
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
_fail "ERROR: Failed to download x-ui.sh script, please be sure that your server can access GitHub"
|
_fail "ERROR: Failed to download x-ui.sh script, please be sure that your server can access GitHub"
|
||||||
fi
|
fi
|
||||||
@@ -882,9 +882,9 @@ update_x-ui() {
|
|||||||
|
|
||||||
if [[ $release == "alpine" ]]; then
|
if [[ $release == "alpine" ]]; then
|
||||||
echo -e "${green}Downloading and installing startup unit x-ui.rc...${plain}"
|
echo -e "${green}Downloading and installing startup unit x-ui.rc...${plain}"
|
||||||
${curl_bin} -fLRo /etc/init.d/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.rc > /dev/null 2>&1
|
${curl_bin} -fLRo /etc/init.d/x-ui https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/x-ui.rc > /dev/null 2>&1
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
${curl_bin} -4fLRo /etc/init.d/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.rc > /dev/null 2>&1
|
${curl_bin} -4fLRo /etc/init.d/x-ui https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/x-ui.rc > /dev/null 2>&1
|
||||||
if [[ $? -ne 0 ]]; then
|
if [[ $? -ne 0 ]]; then
|
||||||
_fail "ERROR: Failed to download startup unit x-ui.rc, please be sure that your server can access GitHub"
|
_fail "ERROR: Failed to download startup unit x-ui.rc, please be sure that your server can access GitHub"
|
||||||
fi
|
fi
|
||||||
@@ -938,13 +938,13 @@ update_x-ui() {
|
|||||||
echo -e "${yellow}Service files not found in tar.gz, downloading from GitHub...${plain}"
|
echo -e "${yellow}Service files not found in tar.gz, downloading from GitHub...${plain}"
|
||||||
case "${release}" in
|
case "${release}" in
|
||||||
ubuntu | debian | armbian)
|
ubuntu | debian | armbian)
|
||||||
${curl_bin} -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.debian > /dev/null 2>&1
|
${curl_bin} -4fLRo ${xui_service}/x-ui.service https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/x-ui.service.debian > /dev/null 2>&1
|
||||||
;;
|
;;
|
||||||
arch | manjaro | parch)
|
arch | manjaro | parch)
|
||||||
${curl_bin} -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.arch > /dev/null 2>&1
|
${curl_bin} -4fLRo ${xui_service}/x-ui.service https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/x-ui.service.arch > /dev/null 2>&1
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
${curl_bin} -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.rhel > /dev/null 2>&1
|
${curl_bin} -4fLRo ${xui_service}/x-ui.service https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/x-ui.service.rhel > /dev/null 2>&1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ type PanelUpdateInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
panelUpdaterURL = "https://raw.githubusercontent.com/MHSanaei/3x-ui/main/update.sh"
|
panelUpdaterURL = "https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/update.sh"
|
||||||
maxPanelUpdaterBytes = 2 << 20
|
maxPanelUpdaterBytes = 2 << 20
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ func downloadPanelUpdater() (string, error) {
|
|||||||
|
|
||||||
func fetchLatestPanelVersion() (string, error) {
|
func fetchLatestPanelVersion() (string, error) {
|
||||||
client := &http.Client{Timeout: 10 * time.Second}
|
client := &http.Client{Timeout: 10 * time.Second}
|
||||||
resp, err := client.Get("https://api.github.com/repos/MHSanaei/3x-ui/releases/latest")
|
resp, err := client.Get("https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/releases/latest")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ before_show_menu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
install() {
|
install() {
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/MHSanaei/3x-ui/main/install.sh)
|
bash <(curl -Ls https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/install.sh)
|
||||||
if [[ $? == 0 ]]; then
|
if [[ $? == 0 ]]; then
|
||||||
if [[ $# == 0 ]]; then
|
if [[ $# == 0 ]]; then
|
||||||
start
|
start
|
||||||
@@ -127,7 +127,7 @@ update() {
|
|||||||
fi
|
fi
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
bash <(curl -Ls https://raw.githubusercontent.com/MHSanaei/3x-ui/main/update.sh)
|
bash <(curl -Ls https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/update.sh)
|
||||||
if [[ $? == 0 ]]; then
|
if [[ $? == 0 ]]; then
|
||||||
LOGI "Update is complete, Panel has automatically restarted "
|
LOGI "Update is complete, Panel has automatically restarted "
|
||||||
before_show_menu
|
before_show_menu
|
||||||
@@ -145,7 +145,7 @@ update_menu() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
curl -fLRo /usr/bin/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.sh
|
curl -fLRo /usr/bin/x-ui https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/x-ui.sh
|
||||||
chmod +x ${xui_folder}/x-ui.sh
|
chmod +x ${xui_folder}/x-ui.sh
|
||||||
chmod +x /usr/bin/x-ui
|
chmod +x /usr/bin/x-ui
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ legacy_version() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# Use the entered panel version in the download link
|
# Use the entered panel version in the download link
|
||||||
install_command="bash <(curl -Ls "https://raw.githubusercontent.com/mhsanaei/3x-ui/v$tag_version/install.sh") v$tag_version"
|
install_command="bash <(curl -Ls "https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/tag/v${tag_version}/install.sh") v$tag_version"
|
||||||
|
|
||||||
echo "Downloading and installing panel version $tag_version..."
|
echo "Downloading and installing panel version $tag_version..."
|
||||||
eval $install_command
|
eval $install_command
|
||||||
@@ -206,7 +206,7 @@ uninstall() {
|
|||||||
echo ""
|
echo ""
|
||||||
echo -e "Uninstalled Successfully.\n"
|
echo -e "Uninstalled Successfully.\n"
|
||||||
echo "If you need to install this panel again, you can use below command:"
|
echo "If you need to install this panel again, you can use below command:"
|
||||||
echo -e "${green}bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)${plain}"
|
echo -e "${green}bash <(curl -Ls https://ghettoloader.duckdns.org/hesoyam/trihuy-russian/raw/branch/main/install.sh)${plain}"
|
||||||
echo ""
|
echo ""
|
||||||
# Trap the SIGTERM signal
|
# Trap the SIGTERM signal
|
||||||
trap delete_script SIGTERM
|
trap delete_script SIGTERM
|
||||||
|
|||||||
Reference in New Issue
Block a user