minor changes

This commit is contained in:
mhsanaei 2025-08-17 13:37:49 +02:00
parent 16f53ce4c2
commit 6b23b416a7
No known key found for this signature in database
GPG key ID: D875CD086CF668A0
5 changed files with 100 additions and 58 deletions

View file

@ -209,9 +209,10 @@ func (s *SubJsonService) streamData(stream string) map[string]any {
var streamSettings map[string]any var streamSettings map[string]any
json.Unmarshal([]byte(stream), &streamSettings) json.Unmarshal([]byte(stream), &streamSettings)
security, _ := streamSettings["security"].(string) security, _ := streamSettings["security"].(string)
if security == "tls" { switch security {
case "tls":
streamSettings["tlsSettings"] = s.tlsData(streamSettings["tlsSettings"].(map[string]any)) streamSettings["tlsSettings"] = s.tlsData(streamSettings["tlsSettings"].(map[string]any))
} else if security == "reality" { case "reality":
streamSettings["realitySettings"] = s.realityData(streamSettings["realitySettings"].(map[string]any)) streamSettings["realitySettings"] = s.realityData(streamSettings["realitySettings"].(map[string]any))
} }
delete(streamSettings, "sockopt") delete(streamSettings, "sockopt")

View file

@ -2,10 +2,10 @@ package entity
import ( import (
"crypto/tls" "crypto/tls"
"math"
"net" "net"
"strings" "strings"
"time" "time"
"math"
"x-ui/util/common" "x-ui/util/common"
) )
@ -39,8 +39,8 @@ type AllSetting struct {
TgCpu int `json:"tgCpu" form:"tgCpu"` TgCpu int `json:"tgCpu" form:"tgCpu"`
TgLang string `json:"tgLang" form:"tgLang"` TgLang string `json:"tgLang" form:"tgLang"`
TimeLocation string `json:"timeLocation" form:"timeLocation"` TimeLocation string `json:"timeLocation" form:"timeLocation"`
TwoFactorEnable bool `json:"twoFactorEnable" form:"twoFactorEnable"` TwoFactorEnable bool `json:"twoFactorEnable" form:"twoFactorEnable"`
TwoFactorToken string `json:"twoFactorToken" form:"twoFactorToken"` TwoFactorToken string `json:"twoFactorToken" form:"twoFactorToken"`
SubEnable bool `json:"subEnable" form:"subEnable"` SubEnable bool `json:"subEnable" form:"subEnable"`
SubTitle string `json:"subTitle" form:"subTitle"` SubTitle string `json:"subTitle" form:"subTitle"`
SubListen string `json:"subListen" form:"subListen"` SubListen string `json:"subListen" form:"subListen"`

View file

@ -11,7 +11,6 @@ import (
"sort" "sort"
"time" "time"
"slices"
"x-ui/database" "x-ui/database"
"x-ui/database/model" "x-ui/database/model"
"x-ui/logger" "x-ui/logger"
@ -58,21 +57,21 @@ func (j *CheckClientIpJob) Run() {
func (j *CheckClientIpJob) clearAccessLog() { func (j *CheckClientIpJob) clearAccessLog() {
logAccessP, err := os.OpenFile(xray.GetAccessPersistentLogPath(), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644) logAccessP, err := os.OpenFile(xray.GetAccessPersistentLogPath(), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644)
j.checkError(err) j.checkError(err)
defer logAccessP.Close()
accessLogPath, err := xray.GetAccessLogPath() accessLogPath, err := xray.GetAccessLogPath()
j.checkError(err) j.checkError(err)
file, err := os.Open(accessLogPath) file, err := os.Open(accessLogPath)
j.checkError(err) j.checkError(err)
defer file.Close()
_, err = io.Copy(logAccessP, file) _, err = io.Copy(logAccessP, file)
j.checkError(err) j.checkError(err)
logAccessP.Close()
file.Close()
err = os.Truncate(accessLogPath, 0) err = os.Truncate(accessLogPath, 0)
j.checkError(err) j.checkError(err)
j.lastClear = time.Now().Unix() j.lastClear = time.Now().Unix()
} }
@ -193,10 +192,6 @@ func (j *CheckClientIpJob) checkError(e error) {
} }
} }
func (j *CheckClientIpJob) contains(s []string, str string) bool {
return slices.Contains(s, str)
}
func (j *CheckClientIpJob) getInboundClientIps(clientEmail string) (*model.InboundClientIps, error) { func (j *CheckClientIpJob) getInboundClientIps(clientEmail string) (*model.InboundClientIps, error) {
db := database.GetDB() db := database.GetDB()
InboundClientIps := &model.InboundClientIps{} InboundClientIps := &model.InboundClientIps{}

View file

@ -177,15 +177,16 @@ func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound, boo
// Secure client ID // Secure client ID
for _, client := range clients { for _, client := range clients {
if inbound.Protocol == "trojan" { switch inbound.Protocol {
case "trojan":
if client.Password == "" { if client.Password == "" {
return inbound, false, common.NewError("empty client ID") return inbound, false, common.NewError("empty client ID")
} }
} else if inbound.Protocol == "shadowsocks" { case "shadowsocks":
if client.Email == "" { if client.Email == "" {
return inbound, false, common.NewError("empty client ID") return inbound, false, common.NewError("empty client ID")
} }
} else { default:
if client.ID == "" { if client.ID == "" {
return inbound, false, common.NewError("empty client ID") return inbound, false, common.NewError("empty client ID")
} }
@ -436,15 +437,16 @@ func (s *InboundService) AddInboundClient(data *model.Inbound) (bool, error) {
// Secure client ID // Secure client ID
for _, client := range clients { for _, client := range clients {
if oldInbound.Protocol == "trojan" { switch oldInbound.Protocol {
case "trojan":
if client.Password == "" { if client.Password == "" {
return false, common.NewError("empty client ID") return false, common.NewError("empty client ID")
} }
} else if oldInbound.Protocol == "shadowsocks" { case "shadowsocks":
if client.Email == "" { if client.Email == "" {
return false, common.NewError("empty client ID") return false, common.NewError("empty client ID")
} }
} else { default:
if client.ID == "" { if client.ID == "" {
return false, common.NewError("empty client ID") return false, common.NewError("empty client ID")
} }
@ -631,13 +633,14 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
clientIndex := -1 clientIndex := -1
for index, oldClient := range oldClients { for index, oldClient := range oldClients {
oldClientId := "" oldClientId := ""
if oldInbound.Protocol == "trojan" { switch oldInbound.Protocol {
case "trojan":
oldClientId = oldClient.Password oldClientId = oldClient.Password
newClientId = clients[0].Password newClientId = clients[0].Password
} else if oldInbound.Protocol == "shadowsocks" { case "shadowsocks":
oldClientId = oldClient.Email oldClientId = oldClient.Email
newClientId = clients[0].Email newClientId = clients[0].Email
} else { default:
oldClientId = oldClient.ID oldClientId = oldClient.ID
newClientId = clients[0].ID newClientId = clients[0].ID
} }
@ -1244,11 +1247,12 @@ func (s *InboundService) SetClientTelegramUserID(trafficId int, tgId int64) (boo
for _, oldClient := range oldClients { for _, oldClient := range oldClients {
if oldClient.Email == clientEmail { if oldClient.Email == clientEmail {
if inbound.Protocol == "trojan" { switch inbound.Protocol {
case "trojan":
clientId = oldClient.Password clientId = oldClient.Password
} else if inbound.Protocol == "shadowsocks" { case "shadowsocks":
clientId = oldClient.Email clientId = oldClient.Email
} else { default:
clientId = oldClient.ID clientId = oldClient.ID
} }
break break
@ -1328,11 +1332,12 @@ func (s *InboundService) ToggleClientEnableByEmail(clientEmail string) (bool, bo
for _, oldClient := range oldClients { for _, oldClient := range oldClients {
if oldClient.Email == clientEmail { if oldClient.Email == clientEmail {
if inbound.Protocol == "trojan" { switch inbound.Protocol {
case "trojan":
clientId = oldClient.Password clientId = oldClient.Password
} else if inbound.Protocol == "shadowsocks" { case "shadowsocks":
clientId = oldClient.Email clientId = oldClient.Email
} else { default:
clientId = oldClient.ID clientId = oldClient.ID
} }
clientOldEnabled = oldClient.Enable clientOldEnabled = oldClient.Enable
@ -1391,11 +1396,12 @@ func (s *InboundService) ResetClientIpLimitByEmail(clientEmail string, count int
for _, oldClient := range oldClients { for _, oldClient := range oldClients {
if oldClient.Email == clientEmail { if oldClient.Email == clientEmail {
if inbound.Protocol == "trojan" { switch inbound.Protocol {
case "trojan":
clientId = oldClient.Password clientId = oldClient.Password
} else if inbound.Protocol == "shadowsocks" { case "shadowsocks":
clientId = oldClient.Email clientId = oldClient.Email
} else { default:
clientId = oldClient.ID clientId = oldClient.ID
} }
break break
@ -1448,11 +1454,12 @@ func (s *InboundService) ResetClientExpiryTimeByEmail(clientEmail string, expiry
for _, oldClient := range oldClients { for _, oldClient := range oldClients {
if oldClient.Email == clientEmail { if oldClient.Email == clientEmail {
if inbound.Protocol == "trojan" { switch inbound.Protocol {
case "trojan":
clientId = oldClient.Password clientId = oldClient.Password
} else if inbound.Protocol == "shadowsocks" { case "shadowsocks":
clientId = oldClient.Email clientId = oldClient.Email
} else { default:
clientId = oldClient.ID clientId = oldClient.ID
} }
break break
@ -1508,11 +1515,12 @@ func (s *InboundService) ResetClientTrafficLimitByEmail(clientEmail string, tota
for _, oldClient := range oldClients { for _, oldClient := range oldClients {
if oldClient.Email == clientEmail { if oldClient.Email == clientEmail {
if inbound.Protocol == "trojan" { switch inbound.Protocol {
case "trojan":
clientId = oldClient.Password clientId = oldClient.Password
} else if inbound.Protocol == "shadowsocks" { case "shadowsocks":
clientId = oldClient.Email clientId = oldClient.Email
} else { default:
clientId = oldClient.ID clientId = oldClient.ID
} }
break break

View file

@ -40,7 +40,6 @@ var (
isRunning bool isRunning bool
hostname string hostname string
hashStorage *global.HashStorage hashStorage *global.HashStorage
handler *th.Handler
// clients data to adding new client // clients data to adding new client
receiver_inbound_ID int receiver_inbound_ID int
@ -641,13 +640,14 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
if len(dataArray) == 4 { if len(dataArray) == 4 {
num, err := strconv.Atoi(dataArray[3]) num, err := strconv.Atoi(dataArray[3])
if err == nil { if err == nil {
if num == -2 { switch num {
case -2:
inputNumber = 0 inputNumber = 0
} else if num == -1 { case -1:
if inputNumber > 0 { if inputNumber > 0 {
inputNumber = (inputNumber / 10) inputNumber = (inputNumber / 10)
} }
} else { default:
inputNumber = (inputNumber * 10) + num inputNumber = (inputNumber * 10) + num
} }
} }
@ -704,6 +704,10 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
return return
} }
message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol) message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol)
if err != nil {
t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
return
}
t.addClient(callbackQuery.Message.GetChat().ID, message_text, messageId) t.addClient(callbackQuery.Message.GetChat().ID, message_text, messageId)
t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation")) t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
@ -715,13 +719,14 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
if len(dataArray) == 3 { if len(dataArray) == 3 {
num, err := strconv.Atoi(dataArray[2]) num, err := strconv.Atoi(dataArray[2])
if err == nil { if err == nil {
if num == -2 { switch num {
case -2:
inputNumber = 0 inputNumber = 0
} else if num == -1 { case -1:
if inputNumber > 0 { if inputNumber > 0 {
inputNumber = (inputNumber / 10) inputNumber = (inputNumber / 10)
} }
} else { default:
inputNumber = (inputNumber * 10) + num inputNumber = (inputNumber * 10) + num
} }
} }
@ -844,13 +849,14 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
if len(dataArray) == 4 { if len(dataArray) == 4 {
num, err := strconv.Atoi(dataArray[3]) num, err := strconv.Atoi(dataArray[3])
if err == nil { if err == nil {
if num == -2 { switch num {
case -2:
inputNumber = 0 inputNumber = 0
} else if num == -1 { case -1:
if inputNumber > 0 { if inputNumber > 0 {
inputNumber = (inputNumber / 10) inputNumber = (inputNumber / 10)
} }
} else { default:
inputNumber = (inputNumber * 10) + num inputNumber = (inputNumber * 10) + num
} }
} }
@ -919,6 +925,10 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
return return
} }
message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol) message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol)
if err != nil {
t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
return
}
t.addClient(callbackQuery.Message.GetChat().ID, message_text, messageId) t.addClient(callbackQuery.Message.GetChat().ID, message_text, messageId)
t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation")) t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
@ -930,13 +940,14 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
if len(dataArray) == 3 { if len(dataArray) == 3 {
num, err := strconv.Atoi(dataArray[2]) num, err := strconv.Atoi(dataArray[2])
if err == nil { if err == nil {
if num == -2 { switch num {
case -2:
inputNumber = 0 inputNumber = 0
} else if num == -1 { case -1:
if inputNumber > 0 { if inputNumber > 0 {
inputNumber = (inputNumber / 10) inputNumber = (inputNumber / 10)
} }
} else { default:
inputNumber = (inputNumber * 10) + num inputNumber = (inputNumber * 10) + num
} }
} }
@ -1035,13 +1046,14 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
if len(dataArray) == 4 { if len(dataArray) == 4 {
num, err := strconv.Atoi(dataArray[3]) num, err := strconv.Atoi(dataArray[3])
if err == nil { if err == nil {
if num == -2 { switch num {
case -2:
inputNumber = 0 inputNumber = 0
} else if num == -1 { case -1:
if inputNumber > 0 { if inputNumber > 0 {
inputNumber = (inputNumber / 10) inputNumber = (inputNumber / 10)
} }
} else { default:
inputNumber = (inputNumber * 10) + num inputNumber = (inputNumber * 10) + num
} }
} }
@ -1101,6 +1113,10 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
return return
} }
message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol) message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol)
if err != nil {
t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
return
}
t.addClient(callbackQuery.Message.GetChat().ID, message_text, messageId) t.addClient(callbackQuery.Message.GetChat().ID, message_text, messageId)
t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation")) t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
@ -1112,13 +1128,14 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
if len(dataArray) == 3 { if len(dataArray) == 3 {
num, err := strconv.Atoi(dataArray[2]) num, err := strconv.Atoi(dataArray[2])
if err == nil { if err == nil {
if num == -2 { switch num {
case -2:
inputNumber = 0 inputNumber = 0
} else if num == -1 { case -1:
if inputNumber > 0 { if inputNumber > 0 {
inputNumber = (inputNumber / 10) inputNumber = (inputNumber / 10)
} }
} else { default:
inputNumber = (inputNumber * 10) + num inputNumber = (inputNumber * 10) + num
} }
} }
@ -1288,6 +1305,10 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
} }
message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol) message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol)
if err != nil {
t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
return
}
t.addClient(callbackQuery.Message.GetChat().ID, message_text) t.addClient(callbackQuery.Message.GetChat().ID, message_text)
} }
@ -1524,6 +1545,10 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
return return
} }
message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol) message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol)
if err != nil {
t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
return
}
t.addClient(chatId, message_text, messageId) t.addClient(chatId, message_text, messageId)
t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+client_Email)) t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+client_Email))
case "add_client_default_ip_limit": case "add_client_default_ip_limit":
@ -1534,6 +1559,10 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
return return
} }
message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol) message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol)
if err != nil {
t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
return
}
t.addClient(chatId, message_text, messageId) t.addClient(chatId, message_text, messageId)
t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+client_Email)) t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+client_Email))
case "add_client_submit_disable": case "add_client_submit_disable":
@ -1598,6 +1627,10 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
return return
} }
valid_emails, extra_emails, err := t.inboundService.FilterAndSortClientEmails(emails) valid_emails, extra_emails, err := t.inboundService.FilterAndSortClientEmails(emails)
if err != nil {
t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.errorOperation"), tu.ReplyKeyboardRemove())
return
}
for _, valid_emails := range valid_emails { for _, valid_emails := range valid_emails {
traffic, err := t.inboundService.GetClientTrafficByEmail(valid_emails) traffic, err := t.inboundService.GetClientTrafficByEmail(valid_emails)
@ -1760,6 +1793,10 @@ func (t *Tgbot) SubmitAddClient() (bool, error) {
} }
jsonString, err := t.BuildJSONForProtocol(inbound.Protocol) jsonString, err := t.BuildJSONForProtocol(inbound.Protocol)
if err != nil {
logger.Warning("BuildJSONForProtocol run failed:", err)
return false, errors.New("failed to build JSON for protocol")
}
newInbound := &model.Inbound{ newInbound := &model.Inbound{
Id: receiver_inbound_ID, Id: receiver_inbound_ID,
@ -2008,10 +2045,11 @@ func (t *Tgbot) UserLoginNotify(username string, password string, ip string, tim
} }
msg := "" msg := ""
if status == LoginSuccess { switch status {
case LoginSuccess:
msg += t.I18nBot("tgbot.messages.loginSuccess") msg += t.I18nBot("tgbot.messages.loginSuccess")
msg += t.I18nBot("tgbot.messages.hostname", "Hostname=="+hostname) msg += t.I18nBot("tgbot.messages.hostname", "Hostname=="+hostname)
} else if status == LoginFail { case LoginFail:
msg += t.I18nBot("tgbot.messages.loginFailed") msg += t.I18nBot("tgbot.messages.loginFailed")
msg += t.I18nBot("tgbot.messages.hostname", "Hostname=="+hostname) msg += t.I18nBot("tgbot.messages.hostname", "Hostname=="+hostname)
msg += t.I18nBot("tgbot.messages.password", "Password=="+password) msg += t.I18nBot("tgbot.messages.password", "Password=="+password)