Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
438a9684ee | ||
|
|
a6000f22a2 | ||
|
|
2ec5eeb442 | ||
|
|
d319476eb6 | ||
|
|
93d52bc86c | ||
|
|
bda5c2c915 | ||
|
|
b838fe2e74 | ||
|
|
604b9be4a0 |
@@ -32,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
||||
|
||||
## Instalar una Versión Personalizada
|
||||
|
||||
Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.3.12`:
|
||||
Para instalar la versión deseada, agrega la versión al final del comando de instalación. Por ejemplo, ver `v2.3.13`:
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.12
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.13
|
||||
```
|
||||
|
||||
## Certificado SSL
|
||||
|
||||
@@ -32,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
||||
|
||||
## Install Custom Version
|
||||
|
||||
To install your desired version, add the version to the end of the installation command. e.g., ver `v2.3.12`:
|
||||
To install your desired version, add the version to the end of the installation command. e.g., ver `v2.3.13`:
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.12
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.13
|
||||
```
|
||||
|
||||
## SSL Certificate
|
||||
@@ -250,6 +250,7 @@ Our platform offers compatibility with a diverse range of architectures and devi
|
||||
- Spanish
|
||||
- Indonesian
|
||||
- Ukrainian
|
||||
- Turkish
|
||||
|
||||
|
||||
## Features
|
||||
@@ -258,7 +259,7 @@ Our platform offers compatibility with a diverse range of architectures and devi
|
||||
- Search within all inbounds and clients
|
||||
- Dark/Light theme
|
||||
- Supports multi-user and multi-protocol
|
||||
- Supports protocols, including VMess, VLESS, Trojan, Shadowsocks, Dokodemo-door, Socks, HTTP, wireguard
|
||||
- Supports protocols, including VMESS, VLESS, Trojan, Shadowsocks, Dokodemo-door, Socks, HTTP, wireguard
|
||||
- Supports XTLS native Protocols, including RPRX-Direct, Vision, REALITY
|
||||
- Traffic statistics, traffic limit, expiration time limit
|
||||
- Customizable Xray configuration templates
|
||||
|
||||
@@ -32,10 +32,10 @@ bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.
|
||||
|
||||
## 安装指定版本
|
||||
|
||||
要安装所需的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.3.12`:
|
||||
要安装所需的版本,请将该版本添加到安装命令的末尾。 e.g., ver `v2.3.13`:
|
||||
|
||||
```
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.12
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh) v2.3.13
|
||||
```
|
||||
|
||||
## SSL 认证
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.3.12
|
||||
2.3.13
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
type Protocol string
|
||||
|
||||
const (
|
||||
VMess Protocol = "vmess"
|
||||
VMESS Protocol = "vmess"
|
||||
VLESS Protocol = "vless"
|
||||
DOKODEMO Protocol = "dokodemo-door"
|
||||
HTTP Protocol = "http"
|
||||
@@ -86,6 +86,7 @@ type Setting struct {
|
||||
|
||||
type Client struct {
|
||||
ID string `json:"id"`
|
||||
Security string `json:"security"`
|
||||
Password string `json:"password"`
|
||||
Flow string `json:"flow"`
|
||||
Email string `json:"email"`
|
||||
|
||||
20
go.mod
20
go.mod
@@ -16,7 +16,7 @@ require (
|
||||
github.com/valyala/fasthttp v1.55.0
|
||||
github.com/xtls/xray-core v1.8.23
|
||||
go.uber.org/atomic v1.11.0
|
||||
golang.org/x/text v0.16.0
|
||||
golang.org/x/text v0.17.0
|
||||
google.golang.org/grpc v1.65.0
|
||||
gorm.io/driver/sqlite v1.5.6
|
||||
gorm.io/gorm v1.25.11
|
||||
@@ -24,7 +24,7 @@ require (
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/bytedance/sonic v1.12.0 // indirect
|
||||
github.com/bytedance/sonic v1.12.1 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.0 // indirect
|
||||
github.com/cloudflare/circl v1.3.9 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
@@ -57,11 +57,11 @@ require (
|
||||
github.com/mattn/go-sqlite3 v1.14.22 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.19.1 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.20.0 // indirect
|
||||
github.com/pires/go-proxyproto v0.7.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/quic-go v0.45.2 // indirect
|
||||
github.com/quic-go/quic-go v0.46.0 // indirect
|
||||
github.com/refraction-networking/utls v1.6.7 // indirect
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
@@ -84,17 +84,17 @@ require (
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||
golang.org/x/arch v0.9.0 // indirect
|
||||
golang.org/x/crypto v0.25.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
|
||||
golang.org/x/crypto v0.26.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
|
||||
golang.org/x/mod v0.20.0 // indirect
|
||||
golang.org/x/net v0.27.0 // indirect
|
||||
golang.org/x/net v0.28.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.23.0 // indirect
|
||||
golang.org/x/sys v0.24.0 // indirect
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
golang.org/x/tools v0.23.0 // indirect
|
||||
golang.org/x/tools v0.24.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 // indirect
|
||||
|
||||
44
go.sum
44
go.sum
@@ -18,8 +18,8 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||
github.com/bytedance/sonic v1.12.0 h1:YGPgxF9xzaCNvd/ZKdQ28yRovhfMFZQjuk6fKBzZ3ls=
|
||||
github.com/bytedance/sonic v1.12.0/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||
github.com/bytedance/sonic v1.12.1 h1:jWl5Qz1fy7X1ioY74WqO0KjAMtAGQs4sYnjiEBiyX24=
|
||||
github.com/bytedance/sonic v1.12.1/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=
|
||||
github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
@@ -164,10 +164,10 @@ github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJE
|
||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
|
||||
github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0=
|
||||
github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA=
|
||||
github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os=
|
||||
github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo=
|
||||
github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw=
|
||||
github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
|
||||
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
|
||||
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
@@ -188,8 +188,8 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/quic-go v0.45.2 h1:DfqBmqjb4ExSdxRIb/+qXhPC+7k6+DUNZha4oeiC9fY=
|
||||
github.com/quic-go/quic-go v0.45.2/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
|
||||
github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y=
|
||||
github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
|
||||
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
|
||||
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
|
||||
@@ -296,11 +296,11 @@ golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
|
||||
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@@ -314,8 +314,8 @@ golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@@ -339,12 +339,12 @@ golang.org/x/sys v0.0.0-20220804214406-8e32c043e418/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
|
||||
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||
@@ -353,8 +353,8 @@ golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGm
|
||||
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
||||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
||||
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
|
||||
@@ -371,8 +371,8 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA
|
||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4 h1:OsSGQeIIsyOEOimVxLEIL4rwGcnrjOydQaiA2bOnZUM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a h1:EKiZZXueP9/T68B8Nl0GAx9cjbQnCId0yP3qPMgaaHs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
|
||||
4
main.go
4
main.go
@@ -73,11 +73,11 @@ func runWebServer() {
|
||||
|
||||
err := server.Stop()
|
||||
if err != nil {
|
||||
logger.Warning("Error stopping web server:", err)
|
||||
logger.Debug("Error stopping web server:", err)
|
||||
}
|
||||
err = subServer.Stop()
|
||||
if err != nil {
|
||||
logger.Warning("Error stopping sub server:", err)
|
||||
logger.Debug("Error stopping sub server:", err)
|
||||
}
|
||||
|
||||
server = web.NewServer()
|
||||
|
||||
@@ -3,6 +3,7 @@ package sub
|
||||
import (
|
||||
"encoding/base64"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -54,7 +55,10 @@ func (a *SUBController) initRouter(g *gin.RouterGroup) {
|
||||
|
||||
func (a *SUBController) subs(c *gin.Context) {
|
||||
subId := c.Param("subid")
|
||||
host := c.GetHeader("X-Forwarded-Host")
|
||||
var host string
|
||||
if h, err := getHostFromXFH(c.GetHeader("X-Forwarded-Host")); err == nil {
|
||||
host = h
|
||||
}
|
||||
if host == "" {
|
||||
host = c.GetHeader("X-Real-IP")
|
||||
}
|
||||
@@ -89,7 +93,10 @@ func (a *SUBController) subs(c *gin.Context) {
|
||||
|
||||
func (a *SUBController) subJsons(c *gin.Context) {
|
||||
subId := c.Param("subid")
|
||||
host := c.GetHeader("X-Forwarded-Host")
|
||||
var host string
|
||||
if h, err := getHostFromXFH(c.GetHeader("X-Forwarded-Host")); err == nil {
|
||||
host = h
|
||||
}
|
||||
if host == "" {
|
||||
host = c.GetHeader("X-Real-IP")
|
||||
}
|
||||
@@ -113,3 +120,14 @@ func (a *SUBController) subJsons(c *gin.Context) {
|
||||
c.String(200, jsonSub)
|
||||
}
|
||||
}
|
||||
|
||||
func getHostFromXFH(s string) (string, error) {
|
||||
if strings.Contains(s, ":") {
|
||||
realHost, _, err := net.SplitHostPort(s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return realHost, nil
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
@@ -282,6 +282,9 @@ func (s *SubJsonService) genVnext(inbound *model.Inbound, streamSettings json_ut
|
||||
|
||||
usersData[0].ID = client.ID
|
||||
usersData[0].Level = 8
|
||||
if inbound.Protocol == model.VMESS {
|
||||
usersData[0].Security = client.Security
|
||||
}
|
||||
if inbound.Protocol == model.VLESS {
|
||||
usersData[0].Flow = client.Flow
|
||||
usersData[0].Encryption = "none"
|
||||
@@ -371,6 +374,7 @@ type UserVnext struct {
|
||||
Encryption string `json:"encryption,omitempty"`
|
||||
Flow string `json:"flow,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Security string `json:"security,omitempty"`
|
||||
Level int `json:"level"`
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ func (s *SubService) getLink(inbound *model.Inbound, email string) string {
|
||||
}
|
||||
|
||||
func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
|
||||
if inbound.Protocol != model.VMess {
|
||||
if inbound.Protocol != model.VMESS {
|
||||
return ""
|
||||
}
|
||||
obj := map[string]interface{}{
|
||||
@@ -281,6 +281,7 @@ func (s *SubService) genVmessLink(inbound *model.Inbound, email string) string {
|
||||
}
|
||||
}
|
||||
obj["id"] = clients[clientIndex].ID
|
||||
obj["scy"] = clients[clientIndex].Security
|
||||
|
||||
externalProxies, _ := stream["externalProxy"].([]interface{})
|
||||
|
||||
|
||||
@@ -69,6 +69,14 @@ const WireguardDomainStrategy = [
|
||||
"ForceIPv6v4"
|
||||
];
|
||||
|
||||
const USERS_SECURITY = {
|
||||
AES_128_GCM: "aes-128-gcm",
|
||||
CHACHA20_POLY1305: "chacha20-poly1305",
|
||||
AUTO: "auto",
|
||||
NONE: "none",
|
||||
ZERO: "zero",
|
||||
};
|
||||
|
||||
Object.freeze(Protocols);
|
||||
Object.freeze(SSMethods);
|
||||
Object.freeze(TLS_FLOW_CONTROL);
|
||||
@@ -76,6 +84,7 @@ Object.freeze(UTLS_FINGERPRINT);
|
||||
Object.freeze(ALPN_OPTION);
|
||||
Object.freeze(OutboundDomainStrategies);
|
||||
Object.freeze(WireguardDomainStrategy);
|
||||
Object.freeze(USERS_SECURITY);
|
||||
|
||||
|
||||
class CommonClass {
|
||||
@@ -721,7 +730,7 @@ class Outbound extends CommonClass {
|
||||
|
||||
const port = json.port * 1;
|
||||
|
||||
return new Outbound(json.ps, Protocols.VMess, new Outbound.VmessSettings(json.add, port, json.id), stream);
|
||||
return new Outbound(json.ps, Protocols.VMess, new Outbound.VmessSettings(json.add, port, json.id, json.scy), stream);
|
||||
}
|
||||
|
||||
static fromParamLink(link) {
|
||||
@@ -923,11 +932,12 @@ Outbound.DNSSettings = class extends CommonClass {
|
||||
}
|
||||
};
|
||||
Outbound.VmessSettings = class extends CommonClass {
|
||||
constructor(address, port, id) {
|
||||
constructor(address, port, id, security) {
|
||||
super();
|
||||
this.address = address;
|
||||
this.port = port;
|
||||
this.id = id;
|
||||
this.security = security;
|
||||
}
|
||||
|
||||
static fromJson(json = {}) {
|
||||
@@ -936,6 +946,7 @@ Outbound.VmessSettings = class extends CommonClass {
|
||||
json.vnext[0].address,
|
||||
json.vnext[0].port,
|
||||
json.vnext[0].users[0].id,
|
||||
json.vnext[0].users[0].security,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -944,7 +955,7 @@ Outbound.VmessSettings = class extends CommonClass {
|
||||
vnext: [{
|
||||
address: this.address,
|
||||
port: this.port,
|
||||
users: [{ id: this.id }],
|
||||
users: [{ id: this.id, security: this.security }],
|
||||
}],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -110,6 +110,14 @@ const TCP_CONGESTION_OPTION = {
|
||||
RENO: "reno",
|
||||
};
|
||||
|
||||
const USERS_SECURITY = {
|
||||
AES_128_GCM: "aes-128-gcm",
|
||||
CHACHA20_POLY1305: "chacha20-poly1305",
|
||||
AUTO: "auto",
|
||||
NONE: "none",
|
||||
ZERO: "zero",
|
||||
};
|
||||
|
||||
Object.freeze(Protocols);
|
||||
Object.freeze(SSMethods);
|
||||
Object.freeze(XTLS_FLOW_CONTROL);
|
||||
@@ -122,6 +130,7 @@ Object.freeze(SNIFFING_OPTION);
|
||||
Object.freeze(USAGE_OPTION);
|
||||
Object.freeze(DOMAIN_STRATEGY_OPTION);
|
||||
Object.freeze(TCP_CONGESTION_OPTION);
|
||||
Object.freeze(USERS_SECURITY);
|
||||
|
||||
class XrayCommonClass {
|
||||
|
||||
@@ -546,9 +555,9 @@ class SplitHTTPStreamSettings extends XrayCommonClass {
|
||||
path = '/',
|
||||
host = '',
|
||||
headers = [],
|
||||
scMaxConcurrentPosts = 100,
|
||||
scMaxEachPostBytes = 1000000,
|
||||
scMinPostsIntervalMs = 30,
|
||||
scMaxConcurrentPosts = "100-200",
|
||||
scMaxEachPostBytes = "1000000-2000000",
|
||||
scMinPostsIntervalMs = "10-50",
|
||||
noSSEHeader = false,
|
||||
) {
|
||||
super();
|
||||
@@ -1446,20 +1455,21 @@ class Inbound extends XrayCommonClass {
|
||||
this.sniffing = new Sniffing();
|
||||
}
|
||||
|
||||
genVmessLink(address = '', port = this.port, forceTls, remark = '', clientId) {
|
||||
genVmessLink(address = '', port = this.port, forceTls, remark = '', clientId, security) {
|
||||
if (this.protocol !== Protocols.VMESS) {
|
||||
return '';
|
||||
}
|
||||
const security = forceTls == 'same' ? this.stream.security : forceTls;
|
||||
const tls = forceTls == 'same' ? this.stream.security : forceTls;
|
||||
let obj = {
|
||||
v: '2',
|
||||
ps: remark,
|
||||
add: address,
|
||||
port: port,
|
||||
id: clientId,
|
||||
scy: security,
|
||||
net: this.stream.network,
|
||||
type: 'none',
|
||||
tls: security,
|
||||
tls: tls,
|
||||
};
|
||||
const network = this.stream.network;
|
||||
if (network === 'tcp') {
|
||||
@@ -1870,7 +1880,7 @@ class Inbound extends XrayCommonClass {
|
||||
genLink(address = '', port = this.port, forceTls = 'same', remark = '', client) {
|
||||
switch (this.protocol) {
|
||||
case Protocols.VMESS:
|
||||
return this.genVmessLink(address, port, forceTls, remark, client.id);
|
||||
return this.genVmessLink(address, port, forceTls, remark, client.id, client.security);
|
||||
case Protocols.VLESS:
|
||||
return this.genVLESSLink(address, port, forceTls, remark, client.id, client.flow);
|
||||
case Protocols.SHADOWSOCKS:
|
||||
@@ -2007,24 +2017,24 @@ Inbound.Settings = class extends XrayCommonClass {
|
||||
|
||||
Inbound.VmessSettings = class extends Inbound.Settings {
|
||||
constructor(protocol,
|
||||
vmesses = [new Inbound.VmessSettings.Vmess()]) {
|
||||
vmesses = [new Inbound.VmessSettings.VMESS()]) {
|
||||
super(protocol);
|
||||
this.vmesses = vmesses;
|
||||
}
|
||||
|
||||
indexOfVmessById(id) {
|
||||
return this.vmesses.findIndex(vmess => vmess.id === id);
|
||||
return this.vmesses.findIndex(VMESS => VMESS.id === id);
|
||||
}
|
||||
|
||||
addVmess(vmess) {
|
||||
if (this.indexOfVmessById(vmess.id) >= 0) {
|
||||
addVmess(VMESS) {
|
||||
if (this.indexOfVmessById(VMESS.id) >= 0) {
|
||||
return false;
|
||||
}
|
||||
this.vmesses.push(vmess);
|
||||
this.vmesses.push(VMESS);
|
||||
}
|
||||
|
||||
delVmess(vmess) {
|
||||
const i = this.indexOfVmessById(vmess.id);
|
||||
delVmess(VMESS) {
|
||||
const i = this.indexOfVmessById(VMESS.id);
|
||||
if (i >= 0) {
|
||||
this.vmesses.splice(i, 1);
|
||||
}
|
||||
@@ -2033,7 +2043,7 @@ Inbound.VmessSettings = class extends Inbound.Settings {
|
||||
static fromJson(json = {}) {
|
||||
return new Inbound.VmessSettings(
|
||||
Protocols.VMESS,
|
||||
json.clients.map(client => Inbound.VmessSettings.Vmess.fromJson(client)),
|
||||
json.clients.map(client => Inbound.VmessSettings.VMESS.fromJson(client)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2043,10 +2053,23 @@ Inbound.VmessSettings = class extends Inbound.Settings {
|
||||
};
|
||||
}
|
||||
};
|
||||
Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
|
||||
constructor(id = RandomUtil.randomUUID(), email = RandomUtil.randomLowerAndNum(8), limitIp = 0, totalGB = 0, expiryTime = 0, enable = true, tgId = '', subId = RandomUtil.randomLowerAndNum(16), reset = 0) {
|
||||
|
||||
Inbound.VmessSettings.VMESS = class extends XrayCommonClass {
|
||||
constructor(
|
||||
id = RandomUtil.randomUUID(),
|
||||
security = USERS_SECURITY.AUTO,
|
||||
email = RandomUtil.randomLowerAndNum(8),
|
||||
limitIp = 0,
|
||||
totalGB = 0,
|
||||
expiryTime = 0,
|
||||
enable = true,
|
||||
tgId = '',
|
||||
subId = RandomUtil.randomLowerAndNum(16),
|
||||
reset = 0
|
||||
) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.security = security;
|
||||
this.email = email;
|
||||
this.limitIp = limitIp;
|
||||
this.totalGB = totalGB;
|
||||
@@ -2058,8 +2081,9 @@ Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
|
||||
}
|
||||
|
||||
static fromJson(json = {}) {
|
||||
return new Inbound.VmessSettings.Vmess(
|
||||
return new Inbound.VmessSettings.VMESS(
|
||||
json.id,
|
||||
json.security,
|
||||
json.email,
|
||||
json.limitIp,
|
||||
json.totalGB,
|
||||
@@ -2098,10 +2122,12 @@ Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
|
||||
};
|
||||
|
||||
Inbound.VLESSSettings = class extends Inbound.Settings {
|
||||
constructor(protocol,
|
||||
constructor(
|
||||
protocol,
|
||||
vlesses = [new Inbound.VLESSSettings.VLESS()],
|
||||
decryption = 'none',
|
||||
fallbacks = []) {
|
||||
fallbacks = []
|
||||
) {
|
||||
super(protocol);
|
||||
this.vlesses = vlesses;
|
||||
this.decryption = decryption;
|
||||
@@ -2135,7 +2161,18 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
|
||||
};
|
||||
|
||||
Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
|
||||
constructor(id = RandomUtil.randomUUID(), flow = '', email = RandomUtil.randomLowerAndNum(8), limitIp = 0, totalGB = 0, expiryTime = 0, enable = true, tgId = '', subId = RandomUtil.randomLowerAndNum(16), reset = 0) {
|
||||
constructor(
|
||||
id = RandomUtil.randomUUID(),
|
||||
flow = '',
|
||||
email = RandomUtil.randomLowerAndNum(8),
|
||||
limitIp = 0,
|
||||
totalGB = 0,
|
||||
expiryTime = 0,
|
||||
enable = true,
|
||||
tgId = '',
|
||||
subId = RandomUtil.randomLowerAndNum(16),
|
||||
reset = 0
|
||||
) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.flow = flow;
|
||||
@@ -2259,8 +2296,20 @@ Inbound.TrojanSettings = class extends Inbound.Settings {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Inbound.TrojanSettings.Trojan = class extends XrayCommonClass {
|
||||
constructor(password = RandomUtil.randomSeq(10), flow = '', email = RandomUtil.randomLowerAndNum(8), limitIp = 0, totalGB = 0, expiryTime = 0, enable = true, tgId = '', subId = RandomUtil.randomLowerAndNum(16), reset = 0) {
|
||||
constructor(
|
||||
password = RandomUtil.randomSeq(10),
|
||||
flow = '',
|
||||
email = RandomUtil.randomLowerAndNum(8),
|
||||
limitIp = 0,
|
||||
totalGB = 0,
|
||||
expiryTime = 0,
|
||||
enable = true,
|
||||
tgId = '',
|
||||
subId = RandomUtil.randomLowerAndNum(16),
|
||||
reset = 0
|
||||
) {
|
||||
super();
|
||||
this.password = password;
|
||||
this.flow = flow;
|
||||
@@ -2405,7 +2454,18 @@ Inbound.ShadowsocksSettings = class extends Inbound.Settings {
|
||||
};
|
||||
|
||||
Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass {
|
||||
constructor(method = '', password = RandomUtil.randomShadowsocksPassword(), email = RandomUtil.randomLowerAndNum(8), limitIp = 0, totalGB = 0, expiryTime = 0, enable = true, tgId = '', subId = RandomUtil.randomLowerAndNum(16), reset = 0) {
|
||||
constructor(
|
||||
method = '',
|
||||
password = RandomUtil.randomShadowsocksPassword(),
|
||||
email = RandomUtil.randomLowerAndNum(8),
|
||||
limitIp = 0,
|
||||
totalGB = 0,
|
||||
expiryTime = 0,
|
||||
enable = true,
|
||||
tgId = '',
|
||||
subId = RandomUtil.randomLowerAndNum(16),
|
||||
reset = 0
|
||||
) {
|
||||
super();
|
||||
this.method = method;
|
||||
this.password = password;
|
||||
@@ -2477,7 +2537,14 @@ Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass {
|
||||
};
|
||||
|
||||
Inbound.DokodemoSettings = class extends Inbound.Settings {
|
||||
constructor(protocol, address, port, network = 'tcp,udp', followRedirect = false, timeout = 0) {
|
||||
constructor(
|
||||
protocol,
|
||||
address,
|
||||
port,
|
||||
network = 'tcp,udp',
|
||||
followRedirect = false,
|
||||
timeout = 30
|
||||
) {
|
||||
super(protocol);
|
||||
this.address = address;
|
||||
this.port = port;
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
<a-form-item label='{{ i18n "pages.client.clientCount" }}' v-if="clientsBulkModal.emailMethod < 2">
|
||||
<a-input-number v-model="clientsBulkModal.quantity" :min="1" :max="100"></a-input-number>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="inbound.protocol === Protocols.VMESS" label='Security'>
|
||||
<a-select v-model="clientsBulkModal.security" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label='Flow' v-if="clientsBulkModal.inbound.canEnableTlsFlow()">
|
||||
<a-select v-model="clientsBulkModal.flow" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option value="" selected>{{ i18n "none" }}</a-select-option>
|
||||
@@ -146,6 +151,7 @@
|
||||
emailPostfix: "",
|
||||
subId: "",
|
||||
tgId: '',
|
||||
security: "auto",
|
||||
flow: "",
|
||||
delayedStart: false,
|
||||
reset: 0,
|
||||
@@ -168,6 +174,7 @@
|
||||
newClient.email += useNum ? prefix + i.toString() + postfix : prefix + postfix;
|
||||
if (clientsBulkModal.subId.length > 0) newClient.subId = clientsBulkModal.subId;
|
||||
newClient.tgId = clientsBulkModal.tgId;
|
||||
newClient.security = clientsBulkModal.security;
|
||||
newClient.limitIp = clientsBulkModal.limitIp;
|
||||
newClient._totalGB = clientsBulkModal.totalGB;
|
||||
newClient._expiryTime = clientsBulkModal.expiryTime;
|
||||
@@ -203,6 +210,7 @@
|
||||
this.emailPostfix = "";
|
||||
this.subId = "";
|
||||
this.tgId = '';
|
||||
this.security = "auto";
|
||||
this.flow = "";
|
||||
this.dbInbound = new DBInbound(dbInbound);
|
||||
this.inbound = dbInbound.toInbound();
|
||||
@@ -211,7 +219,7 @@
|
||||
},
|
||||
newClient(protocol) {
|
||||
switch (protocol) {
|
||||
case Protocols.VMESS: return new Inbound.VmessSettings.Vmess();
|
||||
case Protocols.VMESS: return new Inbound.VmessSettings.VMESS();
|
||||
case Protocols.VLESS: return new Inbound.VLESSSettings.VLESS();
|
||||
case Protocols.TROJAN: return new Inbound.TrojanSettings.Trojan();
|
||||
case Protocols.SHADOWSOCKS: return new Inbound.ShadowsocksSettings.Shadowsocks(clientsBulkModal.inbound.settings.shadowsockses[0].method);
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
},
|
||||
addClient(protocol, clients) {
|
||||
switch (protocol) {
|
||||
case Protocols.VMESS: return clients.push(new Inbound.VmessSettings.Vmess());
|
||||
case Protocols.VMESS: return clients.push(new Inbound.VmessSettings.VMESS());
|
||||
case Protocols.VLESS: return clients.push(new Inbound.VLESSSettings.VLESS());
|
||||
case Protocols.TROJAN: return clients.push(new Inbound.TrojanSettings.Trojan());
|
||||
case Protocols.SHADOWSOCKS: return clients.push(new Inbound.ShadowsocksSettings.Shadowsocks(clients[0].method));
|
||||
|
||||
@@ -39,6 +39,11 @@
|
||||
</template>
|
||||
<a-input v-model.trim="client.id"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="inbound.protocol === Protocols.VMESS" label='Security'>
|
||||
<a-select v-model="client.security" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="client.email && app.subSettings.enable">
|
||||
<template slot="label">
|
||||
<a-tooltip>
|
||||
|
||||
@@ -160,6 +160,11 @@
|
||||
<a-form-item label='ID'>
|
||||
<a-input v-model.trim="outbound.settings.id"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label='Security'>
|
||||
<a-select v-model="outbound.settings.security" :dropdown-class-name="themeSwitcher.currentTheme">
|
||||
<a-select-option v-for="key in USERS_SECURITY" :value="key">[[ key ]]</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<!-- vless settings -->
|
||||
<template v-if="outbound.canEnableTlsFlow()">
|
||||
|
||||
@@ -9,12 +9,10 @@
|
||||
<table width="100%">
|
||||
<tr class="client-table-header">
|
||||
<th>{{ i18n "pages.inbounds.email" }}</th>
|
||||
<th>Flow</th>
|
||||
<th>ID</th>
|
||||
</tr>
|
||||
<tr v-for="(client, index) in inbound.settings.vlesses" :class="index % 2 == 1 ? 'client-table-odd-row' : ''">
|
||||
<td>[[ client.email ]]</td>
|
||||
<td>[[ client.flow ]]</td>
|
||||
<td>[[ client.id ]]</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
<tr class="client-table-header">
|
||||
<th>{{ i18n "pages.inbounds.email" }}</th>
|
||||
<th>ID</th>
|
||||
<th>Security</th>
|
||||
</tr>
|
||||
<tr v-for="(client, index) in inbound.settings.vmesses" :class="index % 2 == 1 ? 'client-table-odd-row' : ''">
|
||||
<td>[[ client.email ]]</td>
|
||||
<td>[[ client.id ]]</td>
|
||||
<td>[[ client.security ]]</td>
|
||||
</tr>
|
||||
</table>
|
||||
</a-collapse-panel>
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
</a-input-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="Max Concurrent Upload">
|
||||
<a-input-number v-model="inbound.stream.splithttp.scMaxConcurrentPosts" :min="0"></a-input-number>
|
||||
<a-input v-model.trim="inbound.stream.splithttp.scMaxConcurrentPosts"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="Max Upload Size (Byte)">
|
||||
<a-input-number v-model="inbound.stream.splithttp.scMaxEachPostBytes" :min="0"></a-input-number>
|
||||
<a-input v-model.trim="inbound.stream.splithttp.scMaxEachPostBytes"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="Min Upload Interval (Ms)">
|
||||
<a-input-number v-model="inbound.stream.splithttp.scMinPostsIntervalMs" :min="0"></a-input-number>
|
||||
<a-input v-model.trim="inbound.stream.splithttp.scMinPostsIntervalMs"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="No SSE Header">
|
||||
<a-switch v-model="inbound.stream.splithttp.noSSEHeader"></a-switch>
|
||||
|
||||
@@ -523,7 +523,9 @@
|
||||
if (msg.success) {
|
||||
this.loading(true);
|
||||
await PromiseUtil.sleep(5000);
|
||||
let { webCertFile, webKeyFile, webDomain: host, webPort: port, webBasePath: base } = this.allSetting;
|
||||
var { webCertFile, webKeyFile, webDomain: host, webPort: port, webBasePath: base } = this.allSetting;
|
||||
if (host == this.oldAllSetting.webDomain) host = null;
|
||||
if (port == this.oldAllSetting.webPort) port = null;
|
||||
const isTLS = webCertFile !== "" || webKeyFile !== "";
|
||||
const url = buildURL({ host, port, isTLS, base, path: "panel/settings" });
|
||||
window.location.replace(url);
|
||||
|
||||
@@ -10,15 +10,9 @@ import (
|
||||
|
||||
func DomainValidatorMiddleware(domain string) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
host := c.GetHeader("X-Forwarded-Host")
|
||||
if host == "" {
|
||||
host = c.GetHeader("X-Real-IP")
|
||||
}
|
||||
if host == "" {
|
||||
host = c.Request.Host
|
||||
if colonIndex := strings.LastIndex(host, ":"); colonIndex != -1 {
|
||||
host, _, _ = net.SplitHostPort(host)
|
||||
}
|
||||
host := c.Request.Host
|
||||
if colonIndex := strings.LastIndex(host, ":"); colonIndex != -1 {
|
||||
host, _, _ = net.SplitHostPort(c.Request.Host)
|
||||
}
|
||||
|
||||
if host != domain {
|
||||
|
||||
@@ -490,6 +490,7 @@ func (s *InboundService) AddInboundClient(data *model.Inbound) (bool, error) {
|
||||
err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]interface{}{
|
||||
"email": client.Email,
|
||||
"id": client.ID,
|
||||
"security": client.Security,
|
||||
"flow": client.Flow,
|
||||
"password": client.Password,
|
||||
"cipher": cipher,
|
||||
@@ -711,6 +712,7 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
|
||||
err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]interface{}{
|
||||
"email": clients[0].Email,
|
||||
"id": clients[0].ID,
|
||||
"security": clients[0].Security,
|
||||
"flow": clients[0].Flow,
|
||||
"password": clients[0].Password,
|
||||
"cipher": cipher,
|
||||
@@ -1559,6 +1561,7 @@ func (s *InboundService) ResetClientTraffic(id int, clientEmail string) (bool, e
|
||||
err1 := s.xrayApi.AddUser(string(inbound.Protocol), inbound.Tag, map[string]interface{}{
|
||||
"email": client.Email,
|
||||
"id": client.ID,
|
||||
"security": client.Security,
|
||||
"flow": client.Flow,
|
||||
"password": client.Password,
|
||||
"cipher": cipher,
|
||||
|
||||
Reference in New Issue
Block a user