Compare commits

...

6 Commits

Author SHA1 Message Date
mhsanaei
b7164805f8 v2.6.2 2025-07-06 20:58:10 +02:00
mhsanaei
bbdeb65291 new alternative to get public IP address 2025-07-06 20:45:58 +02:00
Shishkevich D.
038cf34219 chore: return automatic generation of shadowsocks keys 2025-07-06 15:20:41 +07:00
Shishkevich D.
98a1517470 fix: login title shifts the input fields
* chore: revert "fix: reduced login title font-size for mobile (#3105)"

* chore: short login title translation for russian

* chore: change login title translation for ukrainian
2025-07-06 13:22:09 +07:00
mhsanaei
ce76cedb0d fixed: mux #3185 2025-07-04 14:02:33 +02:00
mhsanaei
24a313d605 fixed: type #3186 2025-07-04 13:25:24 +02:00
11 changed files with 75 additions and 26 deletions

View File

@@ -1 +1 @@
2.6.1
2.6.2

View File

@@ -85,7 +85,10 @@ config_after_install() {
local existing_hasDefaultCredential=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'hasDefaultCredential: .+' | awk '{print $2}')
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}')
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}')
local server_ip=$(curl -s https://api.ipify.org)
local server_ip=$(curl -s --max-time 3 https://api.ipify.org)
if [ -z "$server_ip" ]; then
server_ip=$(curl -s --max-time 3 https://4.ident.me)
fi
if [[ ${#existing_webBasePath} -lt 4 ]]; then
if [[ "$existing_hasDefaultCredential" == "true" ]]; then

View File

@@ -1249,7 +1249,6 @@ class Inbound extends XrayCommonClass {
id: clientId,
scy: security,
net: this.stream.network,
type: 'none',
tls: tls,
};
const network = this.stream.network;
@@ -1284,7 +1283,7 @@ class Inbound extends XrayCommonClass {
const xhttp = this.stream.xhttp;
obj.path = xhttp.path;
obj.host = xhttp.host?.length > 0 ? xhttp.host : this.getHeader(xhttp, 'host');
obj.mode = xhttp.mode;
obj.type = xhttp.mode;
}
if (tls === 'tls') {
@@ -2150,7 +2149,7 @@ Inbound.TrojanSettings.Fallback = class extends XrayCommonClass {
Inbound.ShadowsocksSettings = class extends Inbound.Settings {
constructor(protocol,
method = SSMethods.BLAKE3_AES_256_GCM,
password = '',
password = RandomUtil.randomShadowsocksPassword(),
network = 'tcp,udp',
shadowsockses = [new Inbound.ShadowsocksSettings.Shadowsocks()],
ivCheck = false,
@@ -2188,7 +2187,7 @@ Inbound.ShadowsocksSettings = class extends Inbound.Settings {
Inbound.ShadowsocksSettings.Shadowsocks = class extends XrayCommonClass {
constructor(
method = '',
password = '',
password = RandomUtil.randomShadowsocksPassword(),
email = RandomUtil.randomLowerAndNum(8),
limitIp = 0,
totalGB = 0,

View File

@@ -616,11 +616,27 @@ class Outbound extends CommonClass {
}
canEnableMux() {
if (this.settings.flow && this.settings.flow != '') {
// Disable Mux if flow is set
if (this.settings.flow && this.settings.flow !== '') {
this.mux.enabled = false;
return false;
}
return [Protocols.VMess, Protocols.VLESS, Protocols.Trojan, Protocols.Shadowsocks, Protocols.HTTP, Protocols.Socks].includes(this.protocol);
// Disable Mux if network is xhttp
if (this.stream.network === 'xhttp') {
this.mux.enabled = false;
return false;
}
// Allow Mux only for these protocols
return [
Protocols.VMess,
Protocols.VLESS,
Protocols.Trojan,
Protocols.Shadowsocks,
Protocols.HTTP,
Protocols.Socks
].includes(this.protocol);
}
hasVnext() {

View File

@@ -297,12 +297,6 @@
min-height: 40px;
}
}
@media (max-width: 1024px) {
.title {
font-size: 1.4rem;
}
}
.words-wrapper {
width: 100%;

View File

@@ -47,7 +47,7 @@
}
this.oldClientId = this.getClientId(dbInbound.protocol, clients[index]);
} else {
this.addClient(this.inbound.protocol, this.clients);
this.addClient(this.inbound, this.clients);
}
this.clientStats = this.dbInbound.clientStats.find(row => row.email === this.clients[this.index].email);
this.confirm = confirm;
@@ -59,12 +59,12 @@
default: return client.id;
}
},
addClient(protocol, clients) {
switch (protocol) {
addClient(inbound, clients) {
switch (inbound.protocol) {
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));
case Protocols.SHADOWSOCKS: return clients.push(new Inbound.ShadowsocksSettings.Shadowsocks(clients[0].method, RandomUtil.randomShadowsocksPassword(inbound.settings.method)));
default: return null;
}
},

View File

@@ -104,6 +104,8 @@
}
},
SSMethodChange() {
this.inModal.inbound.settings.password = RandomUtil.randomShadowsocksPassword(this.inModal.inbound.settings.method)
if (this.inModal.inbound.isSSMultiUser) {
if (this.inModal.inbound.settings.shadowsockses.length ==0){
this.inModal.inbound.settings.shadowsockses = [new Inbound.ShadowsocksSettings.Shadowsocks()];
@@ -117,6 +119,9 @@
client.method = "";
})
}
this.inModal.inbound.settings.shadowsockses.forEach(client => {
client.password = RandomUtil.randomShadowsocksPassword(this.inModal.inbound.settings.method)
})
} else {
if (this.inModal.inbound.settings.shadowsockses.length > 0){
this.inModal.inbound.settings.shadowsockses = [];

View File

@@ -94,21 +94,34 @@ type ServerService struct {
inboundService InboundService
cachedIPv4 string
cachedIPv6 string
noIPv6 bool
}
func getPublicIP(url string) string {
resp, err := http.Get(url)
client := &http.Client{
Timeout: 3 * time.Second,
}
resp, err := client.Get(url)
if err != nil {
return "N/A"
}
defer resp.Body.Close()
// Don't retry if access is blocked or region-restricted
if resp.StatusCode == http.StatusForbidden || resp.StatusCode == http.StatusUnavailableForLegalReasons {
return "N/A"
}
if resp.StatusCode != http.StatusOK {
return "N/A"
}
ip, err := io.ReadAll(resp.Body)
if err != nil {
return "N/A"
}
ipString := string(ip)
ipString := strings.TrimSpace(string(ip))
if ipString == "" {
return "N/A"
}
@@ -221,10 +234,23 @@ func (s *ServerService) GetStatus(lastStatus *Status) *Status {
}
// IP fetching with caching
if s.cachedIPv4 == "" || s.cachedIPv6 == "" {
if s.cachedIPv4 == "" {
s.cachedIPv4 = getPublicIP("https://api.ipify.org")
s.cachedIPv6 = getPublicIP("https://api6.ipify.org")
if s.cachedIPv4 == "N/A" {
s.cachedIPv4 = getPublicIP("https://4.ident.me")
}
}
if s.cachedIPv6 == "" && !s.noIPv6 {
s.cachedIPv6 = getPublicIP("https://api6.ipify.org")
if s.cachedIPv6 == "N/A" {
s.cachedIPv6 = getPublicIP("https://6.ident.me")
if s.cachedIPv6 == "N/A" {
s.noIPv6 = true
}
}
}
status.PublicIP.IPv4 = s.cachedIPv4
status.PublicIP.IPv6 = s.cachedIPv6

View File

@@ -84,7 +84,7 @@
[pages.login]
"hello" = "Привет!"
"title" = "Добро пожаловать!"
"title" = "Приветствие!"
"loginAgain" = "Сессия истекла. Войдите в систему снова"
[pages.login.toasts]

View File

@@ -84,7 +84,7 @@
[pages.login]
"hello" = "Привіт"
"title" = "Ласкаво просимо"
"title" = "Привітання!"
"loginAgain" = "Ваш сеанс закінчився, увійдіть знову"
[pages.login.toasts]

10
x-ui.sh
View File

@@ -249,7 +249,10 @@ check_config() {
local existing_webBasePath=$(echo "$info" | grep -Eo 'webBasePath: .+' | awk '{print $2}')
local existing_port=$(echo "$info" | grep -Eo 'port: .+' | awk '{print $2}')
local existing_cert=$(/usr/local/x-ui/x-ui setting -getCert true | grep -Eo 'cert: .+' | awk '{print $2}')
local server_ip=$(curl -s https://api.ipify.org)
local server_ip=$(curl -s --max-time 3 https://api.ipify.org)
if [ -z "$server_ip" ]; then
server_ip=$(curl -s --max-time 3 https://4.ident.me)
fi
if [[ -n "$existing_cert" ]]; then
local domain=$(basename "$(dirname "$existing_cert")")
@@ -1630,7 +1633,10 @@ remove_iplimit() {
}
SSH_port_forwarding() {
local server_ip=$(curl -s https://api.ipify.org)
local server_ip=$(curl -s --max-time 3 https://api.ipify.org)
if [ -z "$server_ip" ]; then
server_ip=$(curl -s --max-time 3 https://4.ident.me)
fi
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}')
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}')
local existing_listenIP=$(/usr/local/x-ui/x-ui setting -getListen true | grep -Eo 'listenIP: .+' | awk '{print $2}')