v2.6.2
This commit is contained in:
心隨緣動 2025-07-12 04:40:46 +08:00 committed by GitHub
parent d529b51631
commit 6b2aee7a41
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 1338 additions and 206 deletions

View File

@ -3,6 +3,7 @@ package service
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"sort"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -413,13 +414,13 @@ func (s *InboundService) AddInboundClient(data *model.Inbound) (bool, error) {
return false, err return false, err
} }
var settings map[string]interface{} var settings map[string]any
err = json.Unmarshal([]byte(data.Settings), &settings) err = json.Unmarshal([]byte(data.Settings), &settings)
if err != nil { if err != nil {
return false, err return false, err
} }
interfaceClients := settings["clients"].([]interface{}) interfaceClients := settings["clients"].([]any)
existEmail, err := s.checkEmailsExistForClients(clients) existEmail, err := s.checkEmailsExistForClients(clients)
if err != nil { if err != nil {
return false, err return false, err
@ -450,13 +451,13 @@ func (s *InboundService) AddInboundClient(data *model.Inbound) (bool, error) {
} }
} }
var oldSettings map[string]interface{} var oldSettings map[string]any
err = json.Unmarshal([]byte(oldInbound.Settings), &oldSettings) err = json.Unmarshal([]byte(oldInbound.Settings), &oldSettings)
if err != nil { if err != nil {
return false, err return false, err
} }
oldClients := oldSettings["clients"].([]interface{}) oldClients := oldSettings["clients"].([]any)
oldClients = append(oldClients, interfaceClients...) oldClients = append(oldClients, interfaceClients...)
oldSettings["clients"] = oldClients oldSettings["clients"] = oldClients
@ -489,7 +490,7 @@ func (s *InboundService) AddInboundClient(data *model.Inbound) (bool, error) {
if oldInbound.Protocol == "shadowsocks" { if oldInbound.Protocol == "shadowsocks" {
cipher = oldSettings["method"].(string) cipher = oldSettings["method"].(string)
} }
err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]interface{}{ err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]any{
"email": client.Email, "email": client.Email,
"id": client.ID, "id": client.ID,
"security": client.Security, "security": client.Security,
@ -519,7 +520,7 @@ func (s *InboundService) DelInboundClient(inboundId int, clientId string) (bool,
logger.Error("Load Old Data Error") logger.Error("Load Old Data Error")
return false, err return false, err
} }
var settings map[string]interface{} var settings map[string]any
err = json.Unmarshal([]byte(oldInbound.Settings), &settings) err = json.Unmarshal([]byte(oldInbound.Settings), &settings)
if err != nil { if err != nil {
return false, err return false, err
@ -534,11 +535,11 @@ func (s *InboundService) DelInboundClient(inboundId int, clientId string) (bool,
client_key = "email" client_key = "email"
} }
interfaceClients := settings["clients"].([]interface{}) interfaceClients := settings["clients"].([]any)
var newClients []interface{} var newClients []any
needApiDel := false needApiDel := false
for _, client := range interfaceClients { for _, client := range interfaceClients {
c := client.(map[string]interface{}) c := client.(map[string]any)
c_id := c[client_key].(string) c_id := c[client_key].(string)
if c_id == clientId { if c_id == clientId {
email, _ = c["email"].(string) email, _ = c["email"].(string)
@ -588,8 +589,12 @@ func (s *InboundService) DelInboundClient(inboundId int, clientId string) (bool,
logger.Debug("Client deleted by api:", email) logger.Debug("Client deleted by api:", email)
needRestart = false needRestart = false
} else { } else {
logger.Debug("Unable to del client by api:", err1) if strings.Contains(err1.Error(), fmt.Sprintf("User %s not found.", email)) {
needRestart = true logger.Debug("User is already deleted. Nothing to do more...")
} else {
logger.Debug("Error in deleting client by api:", err1)
needRestart = true
}
} }
s.xrayApi.Close() s.xrayApi.Close()
} }
@ -603,13 +608,13 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
return false, err return false, err
} }
var settings map[string]interface{} var settings map[string]any
err = json.Unmarshal([]byte(data.Settings), &settings) err = json.Unmarshal([]byte(data.Settings), &settings)
if err != nil { if err != nil {
return false, err return false, err
} }
interfaceClients := settings["clients"].([]interface{}) interfaceClients := settings["clients"].([]any)
oldInbound, err := s.GetInbound(data.Id) oldInbound, err := s.GetInbound(data.Id)
if err != nil { if err != nil {
@ -623,7 +628,7 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
oldEmail := "" oldEmail := ""
newClientId := "" newClientId := ""
clientIndex := 0 clientIndex := -1
for index, oldClient := range oldClients { for index, oldClient := range oldClients {
oldClientId := "" oldClientId := ""
if oldInbound.Protocol == "trojan" { if oldInbound.Protocol == "trojan" {
@ -644,7 +649,7 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
} }
// Validate new client ID // Validate new client ID
if newClientId == "" { if newClientId == "" || clientIndex == -1 {
return false, common.NewError("empty client ID") return false, common.NewError("empty client ID")
} }
@ -658,12 +663,12 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
} }
} }
var oldSettings map[string]interface{} var oldSettings map[string]any
err = json.Unmarshal([]byte(oldInbound.Settings), &oldSettings) err = json.Unmarshal([]byte(oldInbound.Settings), &oldSettings)
if err != nil { if err != nil {
return false, err return false, err
} }
settingsClients := oldSettings["clients"].([]interface{}) settingsClients := oldSettings["clients"].([]any)
settingsClients[clientIndex] = interfaceClients[0] settingsClients[clientIndex] = interfaceClients[0]
oldSettings["clients"] = settingsClients oldSettings["clients"] = settingsClients
@ -713,10 +718,14 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
if oldClients[clientIndex].Enable { if oldClients[clientIndex].Enable {
err1 := s.xrayApi.RemoveUser(oldInbound.Tag, oldEmail) err1 := s.xrayApi.RemoveUser(oldInbound.Tag, oldEmail)
if err1 == nil { if err1 == nil {
logger.Debug("Old client deleted by api:", clients[0].Email) logger.Debug("Old client deleted by api:", oldEmail)
} else { } else {
logger.Debug("Error in deleting client by api:", err1) if strings.Contains(err1.Error(), fmt.Sprintf("User %s not found.", oldEmail)) {
needRestart = true logger.Debug("User is already deleted. Nothing to do more...")
} else {
logger.Debug("Error in deleting client by api:", err1)
needRestart = true
}
} }
} }
if clients[0].Enable { if clients[0].Enable {
@ -724,7 +733,7 @@ func (s *InboundService) UpdateInboundClient(data *model.Inbound, clientId strin
if oldInbound.Protocol == "shadowsocks" { if oldInbound.Protocol == "shadowsocks" {
cipher = oldSettings["method"].(string) cipher = oldSettings["method"].(string)
} }
err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]interface{}{ err1 := s.xrayApi.AddUser(string(oldInbound.Protocol), oldInbound.Tag, map[string]any{
"email": clients[0].Email, "email": clients[0].Email,
"id": clients[0].ID, "id": clients[0].ID,
"security": clients[0].Security, "security": clients[0].Security,
@ -801,7 +810,7 @@ func (s *InboundService) addInboundTraffic(tx *gorm.DB, traffics []*xray.Traffic
for _, traffic := range traffics { for _, traffic := range traffics {
if traffic.IsInbound { if traffic.IsInbound {
err = tx.Model(&model.Inbound{}).Where("tag = ?", traffic.Tag). err = tx.Model(&model.Inbound{}).Where("tag = ?", traffic.Tag).
Updates(map[string]interface{}{ Updates(map[string]any{
"up": gorm.Expr("up + ?", traffic.Up), "up": gorm.Expr("up + ?", traffic.Up),
"down": gorm.Expr("down + ?", traffic.Down), "down": gorm.Expr("down + ?", traffic.Down),
}).Error }).Error
@ -885,13 +894,13 @@ func (s *InboundService) adjustTraffics(tx *gorm.DB, dbClientTraffics []*xray.Cl
return nil, err return nil, err
} }
for inbound_index := range inbounds { for inbound_index := range inbounds {
settings := map[string]interface{}{} settings := map[string]any{}
json.Unmarshal([]byte(inbounds[inbound_index].Settings), &settings) json.Unmarshal([]byte(inbounds[inbound_index].Settings), &settings)
clients, ok := settings["clients"].([]interface{}) clients, ok := settings["clients"].([]any)
if ok { if ok {
var newClients []interface{} var newClients []any
for client_index := range clients { for client_index := range clients {
c := clients[client_index].(map[string]interface{}) c := clients[client_index].(map[string]any)
for traffic_index := range dbClientTraffics { for traffic_index := range dbClientTraffics {
if dbClientTraffics[traffic_index].ExpiryTime < 0 && c["email"] == dbClientTraffics[traffic_index].Email { if dbClientTraffics[traffic_index].ExpiryTime < 0 && c["email"] == dbClientTraffics[traffic_index].Email {
oldExpiryTime := c["expiryTime"].(float64) oldExpiryTime := c["expiryTime"].(float64)
@ -901,7 +910,7 @@ func (s *InboundService) adjustTraffics(tx *gorm.DB, dbClientTraffics []*xray.Cl
break break
} }
} }
newClients = append(newClients, interface{}(c)) newClients = append(newClients, any(c))
} }
settings["clients"] = newClients settings["clients"] = newClients
modifiedSettings, err := json.MarshalIndent(settings, "", " ") modifiedSettings, err := json.MarshalIndent(settings, "", " ")
@ -943,7 +952,7 @@ func (s *InboundService) autoRenewClients(tx *gorm.DB) (bool, int64, error) {
var clientsToAdd []struct { var clientsToAdd []struct {
protocol string protocol string
tag string tag string
client map[string]interface{} client map[string]any
} }
for _, traffic := range traffics { for _, traffic := range traffics {
@ -954,11 +963,11 @@ func (s *InboundService) autoRenewClients(tx *gorm.DB) (bool, int64, error) {
return false, 0, err return false, 0, err
} }
for inbound_index := range inbounds { for inbound_index := range inbounds {
settings := map[string]interface{}{} settings := map[string]any{}
json.Unmarshal([]byte(inbounds[inbound_index].Settings), &settings) json.Unmarshal([]byte(inbounds[inbound_index].Settings), &settings)
clients := settings["clients"].([]interface{}) clients := settings["clients"].([]any)
for client_index := range clients { for client_index := range clients {
c := clients[client_index].(map[string]interface{}) c := clients[client_index].(map[string]any)
for traffic_index, traffic := range traffics { for traffic_index, traffic := range traffics {
if traffic.Email == c["email"].(string) { if traffic.Email == c["email"].(string) {
newExpiryTime := traffic.ExpiryTime newExpiryTime := traffic.ExpiryTime
@ -975,14 +984,14 @@ func (s *InboundService) autoRenewClients(tx *gorm.DB) (bool, int64, error) {
struct { struct {
protocol string protocol string
tag string tag string
client map[string]interface{} client map[string]any
}{ }{
protocol: string(inbounds[inbound_index].Protocol), protocol: string(inbounds[inbound_index].Protocol),
tag: inbounds[inbound_index].Tag, tag: inbounds[inbound_index].Tag,
client: c, client: c,
}) })
} }
clients[client_index] = interface{}(c) clients[client_index] = any(c)
break break
} }
} }
@ -1037,12 +1046,8 @@ func (s *InboundService) disableInvalidInbounds(tx *gorm.DB) (bool, int64, error
if err1 == nil { if err1 == nil {
logger.Debug("Inbound disabled by api:", tag) logger.Debug("Inbound disabled by api:", tag)
} else { } else {
if strings.Contains(err1.Error(), fmt.Sprintf("User %s not found.", tag)) { logger.Debug("Error in disabling inbound by api:", err1)
logger.Debug("User is already disabled. Nothing to do more...") needRestart = true
} else {
logger.Debug("Error in disabling client by api:", err1)
needRestart = true
}
} }
} }
s.xrayApi.Close() s.xrayApi.Close()
@ -1143,7 +1148,7 @@ func (s *InboundService) AddClientStat(tx *gorm.DB, inboundId int, client *model
func (s *InboundService) UpdateClientStat(tx *gorm.DB, email string, client *model.Client) error { func (s *InboundService) UpdateClientStat(tx *gorm.DB, email string, client *model.Client) error {
result := tx.Model(xray.ClientTraffic{}). result := tx.Model(xray.ClientTraffic{}).
Where("email = ?", email). Where("email = ?", email).
Updates(map[string]interface{}{ Updates(map[string]any{
"enable": true, "enable": true,
"email": client.Email, "email": client.Email,
"total": client.TotalGB, "total": client.TotalGB,
@ -1254,18 +1259,18 @@ func (s *InboundService) SetClientTelegramUserID(trafficId int, tgId int64) (boo
return false, common.NewError("Client Not Found For Email:", clientEmail) return false, common.NewError("Client Not Found For Email:", clientEmail)
} }
var settings map[string]interface{} var settings map[string]any
err = json.Unmarshal([]byte(inbound.Settings), &settings) err = json.Unmarshal([]byte(inbound.Settings), &settings)
if err != nil { if err != nil {
return false, err return false, err
} }
clients := settings["clients"].([]interface{}) clients := settings["clients"].([]any)
var newClients []interface{} var newClients []any
for client_index := range clients { for client_index := range clients {
c := clients[client_index].(map[string]interface{}) c := clients[client_index].(map[string]any)
if c["email"] == clientEmail { if c["email"] == clientEmail {
c["tgId"] = tgId c["tgId"] = tgId
newClients = append(newClients, interface{}(c)) newClients = append(newClients, any(c))
} }
} }
settings["clients"] = newClients settings["clients"] = newClients
@ -1339,18 +1344,18 @@ func (s *InboundService) ToggleClientEnableByEmail(clientEmail string) (bool, bo
return false, false, common.NewError("Client Not Found For Email:", clientEmail) return false, false, common.NewError("Client Not Found For Email:", clientEmail)
} }
var settings map[string]interface{} var settings map[string]any
err = json.Unmarshal([]byte(inbound.Settings), &settings) err = json.Unmarshal([]byte(inbound.Settings), &settings)
if err != nil { if err != nil {
return false, false, err return false, false, err
} }
clients := settings["clients"].([]interface{}) clients := settings["clients"].([]any)
var newClients []interface{} var newClients []any
for client_index := range clients { for client_index := range clients {
c := clients[client_index].(map[string]interface{}) c := clients[client_index].(map[string]any)
if c["email"] == clientEmail { if c["email"] == clientEmail {
c["enable"] = !clientOldEnabled c["enable"] = !clientOldEnabled
newClients = append(newClients, interface{}(c)) newClients = append(newClients, any(c))
} }
} }
settings["clients"] = newClients settings["clients"] = newClients
@ -1401,18 +1406,18 @@ func (s *InboundService) ResetClientIpLimitByEmail(clientEmail string, count int
return false, common.NewError("Client Not Found For Email:", clientEmail) return false, common.NewError("Client Not Found For Email:", clientEmail)
} }
var settings map[string]interface{} var settings map[string]any
err = json.Unmarshal([]byte(inbound.Settings), &settings) err = json.Unmarshal([]byte(inbound.Settings), &settings)
if err != nil { if err != nil {
return false, err return false, err
} }
clients := settings["clients"].([]interface{}) clients := settings["clients"].([]any)
var newClients []interface{} var newClients []any
for client_index := range clients { for client_index := range clients {
c := clients[client_index].(map[string]interface{}) c := clients[client_index].(map[string]any)
if c["email"] == clientEmail { if c["email"] == clientEmail {
c["limitIp"] = count c["limitIp"] = count
newClients = append(newClients, interface{}(c)) newClients = append(newClients, any(c))
} }
} }
settings["clients"] = newClients settings["clients"] = newClients
@ -1458,18 +1463,18 @@ func (s *InboundService) ResetClientExpiryTimeByEmail(clientEmail string, expiry
return false, common.NewError("Client Not Found For Email:", clientEmail) return false, common.NewError("Client Not Found For Email:", clientEmail)
} }
var settings map[string]interface{} var settings map[string]any
err = json.Unmarshal([]byte(inbound.Settings), &settings) err = json.Unmarshal([]byte(inbound.Settings), &settings)
if err != nil { if err != nil {
return false, err return false, err
} }
clients := settings["clients"].([]interface{}) clients := settings["clients"].([]any)
var newClients []interface{} var newClients []any
for client_index := range clients { for client_index := range clients {
c := clients[client_index].(map[string]interface{}) c := clients[client_index].(map[string]any)
if c["email"] == clientEmail { if c["email"] == clientEmail {
c["expiryTime"] = expiry_time c["expiryTime"] = expiry_time
newClients = append(newClients, interface{}(c)) newClients = append(newClients, any(c))
} }
} }
settings["clients"] = newClients settings["clients"] = newClients
@ -1518,18 +1523,18 @@ func (s *InboundService) ResetClientTrafficLimitByEmail(clientEmail string, tota
return false, common.NewError("Client Not Found For Email:", clientEmail) return false, common.NewError("Client Not Found For Email:", clientEmail)
} }
var settings map[string]interface{} var settings map[string]any
err = json.Unmarshal([]byte(inbound.Settings), &settings) err = json.Unmarshal([]byte(inbound.Settings), &settings)
if err != nil { if err != nil {
return false, err return false, err
} }
clients := settings["clients"].([]interface{}) clients := settings["clients"].([]any)
var newClients []interface{} var newClients []any
for client_index := range clients { for client_index := range clients {
c := clients[client_index].(map[string]interface{}) c := clients[client_index].(map[string]any)
if c["email"] == clientEmail { if c["email"] == clientEmail {
c["totalGB"] = totalGB * 1024 * 1024 * 1024 c["totalGB"] = totalGB * 1024 * 1024 * 1024
newClients = append(newClients, interface{}(c)) newClients = append(newClients, any(c))
} }
} }
settings["clients"] = newClients settings["clients"] = newClients
@ -1547,7 +1552,7 @@ func (s *InboundService) ResetClientTrafficByEmail(clientEmail string) error {
result := db.Model(xray.ClientTraffic{}). result := db.Model(xray.ClientTraffic{}).
Where("email = ?", clientEmail). Where("email = ?", clientEmail).
Updates(map[string]interface{}{"enable": true, "up": 0, "down": 0}) Updates(map[string]any{"enable": true, "up": 0, "down": 0})
err := result.Error err := result.Error
if err != nil { if err != nil {
@ -1578,14 +1583,14 @@ func (s *InboundService) ResetClientTraffic(id int, clientEmail string) (bool, e
s.xrayApi.Init(p.GetAPIPort()) s.xrayApi.Init(p.GetAPIPort())
cipher := "" cipher := ""
if string(inbound.Protocol) == "shadowsocks" { if string(inbound.Protocol) == "shadowsocks" {
var oldSettings map[string]interface{} var oldSettings map[string]any
err = json.Unmarshal([]byte(inbound.Settings), &oldSettings) err = json.Unmarshal([]byte(inbound.Settings), &oldSettings)
if err != nil { if err != nil {
return false, err return false, err
} }
cipher = oldSettings["method"].(string) cipher = oldSettings["method"].(string)
} }
err1 := s.xrayApi.AddUser(string(inbound.Protocol), inbound.Tag, map[string]interface{}{ err1 := s.xrayApi.AddUser(string(inbound.Protocol), inbound.Tag, map[string]any{
"email": client.Email, "email": client.Email,
"id": client.ID, "id": client.ID,
"security": client.Security, "security": client.Security,
@ -1630,7 +1635,7 @@ func (s *InboundService) ResetAllClientTraffics(id int) error {
result := db.Model(xray.ClientTraffic{}). result := db.Model(xray.ClientTraffic{}).
Where(whereText, id). Where(whereText, id).
Updates(map[string]interface{}{"enable": true, "up": 0, "down": 0}) Updates(map[string]any{"enable": true, "up": 0, "down": 0})
err := result.Error err := result.Error
return err return err
@ -1641,7 +1646,7 @@ func (s *InboundService) ResetAllTraffics() error {
result := db.Model(model.Inbound{}). result := db.Model(model.Inbound{}).
Where("user_id > ?", 0). Where("user_id > ?", 0).
Updates(map[string]interface{}{"up": 0, "down": 0}) Updates(map[string]any{"up": 0, "down": 0})
err := result.Error err := result.Error
return err return err
@ -1677,17 +1682,17 @@ func (s *InboundService) DelDepletedClients(id int) (err error) {
if err != nil { if err != nil {
return err return err
} }
var oldSettings map[string]interface{} var oldSettings map[string]any
err = json.Unmarshal([]byte(oldInbound.Settings), &oldSettings) err = json.Unmarshal([]byte(oldInbound.Settings), &oldSettings)
if err != nil { if err != nil {
return err return err
} }
oldClients := oldSettings["clients"].([]interface{}) oldClients := oldSettings["clients"].([]any)
var newClients []interface{} var newClients []any
for _, client := range oldClients { for _, client := range oldClients {
deplete := false deplete := false
c := client.(map[string]interface{}) c := client.(map[string]any)
for _, email := range emails { for _, email := range emails {
if email == c["email"].(string) { if email == c["email"].(string) {
deplete = true deplete = true
@ -1903,14 +1908,14 @@ func (s *InboundService) MigrationRequirements() {
return return
} }
for inbound_index := range inbounds { for inbound_index := range inbounds {
settings := map[string]interface{}{} settings := map[string]any{}
json.Unmarshal([]byte(inbounds[inbound_index].Settings), &settings) json.Unmarshal([]byte(inbounds[inbound_index].Settings), &settings)
clients, ok := settings["clients"].([]interface{}) clients, ok := settings["clients"].([]any)
if ok { if ok {
// Fix Client configuration problems // Fix Client configuration problems
var newClients []interface{} var newClients []any
for client_index := range clients { for client_index := range clients {
c := clients[client_index].(map[string]interface{}) c := clients[client_index].(map[string]any)
// Add email='' if it is not exists // Add email='' if it is not exists
if _, ok := c["email"]; !ok { if _, ok := c["email"]; !ok {
@ -1919,7 +1924,7 @@ func (s *InboundService) MigrationRequirements() {
// Convert string tgId to int64 // Convert string tgId to int64
if _, ok := c["tgId"]; ok { if _, ok := c["tgId"]; ok {
var tgId interface{} = c["tgId"] var tgId any = c["tgId"]
if tgIdStr, ok2 := tgId.(string); ok2 { if tgIdStr, ok2 := tgId.(string); ok2 {
tgIdInt64, err := strconv.ParseInt(strings.ReplaceAll(tgIdStr, " ", ""), 10, 64) tgIdInt64, err := strconv.ParseInt(strings.ReplaceAll(tgIdStr, " ", ""), 10, 64)
if err == nil { if err == nil {
@ -1934,7 +1939,7 @@ func (s *InboundService) MigrationRequirements() {
c["flow"] = "" c["flow"] = ""
} }
} }
newClients = append(newClients, interface{}(c)) newClients = append(newClients, any(c))
} }
settings["clients"] = newClients settings["clients"] = newClients
modifiedSettings, err := json.MarshalIndent(settings, "", " ") modifiedSettings, err := json.MarshalIndent(settings, "", " ")
@ -1981,14 +1986,14 @@ func (s *InboundService) MigrationRequirements() {
} }
for _, ep := range externalProxy { for _, ep := range externalProxy {
var reverses interface{} var reverses any
var stream map[string]interface{} var stream map[string]any
json.Unmarshal(ep.StreamSettings, &stream) json.Unmarshal(ep.StreamSettings, &stream)
if tlsSettings, ok := stream["tlsSettings"].(map[string]interface{}); ok { if tlsSettings, ok := stream["tlsSettings"].(map[string]any); ok {
if settings, ok := tlsSettings["settings"].(map[string]interface{}); ok { if settings, ok := tlsSettings["settings"].(map[string]any); ok {
if domains, ok := settings["domains"].([]interface{}); ok { if domains, ok := settings["domains"].([]any); ok {
for _, domain := range domains { for _, domain := range domains {
if domainMap, ok := domain.(map[string]interface{}); ok { if domainMap, ok := domain.(map[string]any); ok {
domainMap["forceTls"] = "same" domainMap["forceTls"] = "same"
domainMap["port"] = ep.Port domainMap["port"] = ep.Port
domainMap["dest"] = domainMap["domain"].(string) domainMap["dest"] = domainMap["domain"].(string)
@ -2021,3 +2026,37 @@ func (s *InboundService) MigrateDB() {
func (s *InboundService) GetOnlineClients() []string { func (s *InboundService) GetOnlineClients() []string {
return p.GetOnlineClients() return p.GetOnlineClients()
} }
func (s *InboundService) FilterAndSortClientEmails(emails []string) ([]string, []string, error) {
db := database.GetDB()
// Step 1: Get ClientTraffic records for emails in the input list
var clients []xray.ClientTraffic
err := db.Where("email IN ?", emails).Find(&clients).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, nil, err
}
// Step 2: Sort clients by (Up + Down) descending
sort.Slice(clients, func(i, j int) bool {
return (clients[i].Up + clients[i].Down) > (clients[j].Up + clients[j].Down)
})
// Step 3: Extract sorted valid emails and track found ones
validEmails := make([]string, 0, len(clients))
found := make(map[string]bool)
for _, client := range clients {
validEmails = append(validEmails, client.Email)
found[client.Email] = true
}
// Step 4: Identify emails that were not found in the database
extraEmails := make([]string, 0)
for _, email := range emails {
if !found[email] {
extraEmails = append(extraEmails, email)
}
}
return validEmails, extraEmails, nil
}

View File

@ -24,56 +24,60 @@ import (
var xrayTemplateConfig string var xrayTemplateConfig string
var defaultValueMap = map[string]string{ var defaultValueMap = map[string]string{
"xrayTemplateConfig": xrayTemplateConfig, "xrayTemplateConfig": xrayTemplateConfig,
"webListen": "", "webListen": "",
"webDomain": "", "webDomain": "",
"webPort": "2053", "webPort": "2053",
"webCertFile": "", "webCertFile": "",
"webKeyFile": "", "webKeyFile": "",
"secret": random.Seq(32), "secret": random.Seq(32),
"webBasePath": "/", "webBasePath": "/",
"sessionMaxAge": "60", "sessionMaxAge": "60",
"pageSize": "50", "pageSize": "50",
"expireDiff": "0", "expireDiff": "0",
"trafficDiff": "0", "trafficDiff": "0",
"remarkModel": "-ieo", "remarkModel": "-ieo",
"timeLocation": "Asia/Shanghai", "timeLocation": "Local",
"tgBotEnable": "false", "tgBotEnable": "false",
"tgBotToken": "", "tgBotToken": "",
"tgBotProxy": "", "tgBotProxy": "",
"tgBotAPIServer": "", "tgBotAPIServer": "",
"tgBotChatId": "", "tgBotChatId": "",
"tgRunTime": "@daily", "tgRunTime": "@daily",
"tgBotBackup": "false", "tgBotBackup": "false",
"tgBotLoginNotify": "true", "tgBotLoginNotify": "true",
"tgCpu": "30", "tgCpu": "80",
"tgLang": "zh-Hans", "tgLang": "en-US",
"secretEnable": "false", "twoFactorEnable": "false",
"subEnable": "false", "twoFactorToken": "",
"subListen": "", "subEnable": "false",
"subPort": "2096", "subTitle": "",
"subPath": "/sub/", "subListen": "",
"subDomain": "", "subPort": "2096",
"subCertFile": "", "subPath": "/sub/",
"subKeyFile": "", "subDomain": "",
"subUpdates": "12", "subCertFile": "",
"subEncrypt": "true", "subKeyFile": "",
"subShowInfo": "true", "subUpdates": "12",
"subURI": "", "subEncrypt": "true",
"subJsonPath": "/json/", "subShowInfo": "true",
"subJsonURI": "", "subURI": "",
"subJsonFragment": "", "subJsonPath": "/json/",
"subJsonNoises": "", "subJsonURI": "",
"subJsonMux": "", "subJsonFragment": "",
"subJsonRules": "", "subJsonNoises": "",
"datepicker": "gregorian", "subJsonMux": "",
"warp": "", "subJsonRules": "",
"datepicker": "gregorian",
"warp": "",
"externalTrafficInformEnable": "false",
"externalTrafficInformURI": "",
} }
type SettingService struct{} type SettingService struct{}
func (s *SettingService) GetDefaultJsonConfig() (interface{}, error) { func (s *SettingService) GetDefaultJsonConfig() (any, error) {
var jsonData interface{} var jsonData any
err := json.Unmarshal([]byte(xrayTemplateConfig), &jsonData) err := json.Unmarshal([]byte(xrayTemplateConfig), &jsonData)
if err != nil { if err != nil {
return nil, err return nil, err
@ -163,8 +167,7 @@ func (s *SettingService) ResetSettings() error {
return err return err
} }
return db.Model(model.User{}). return db.Model(model.User{}).
Where("1 = 1"). Where("1 = 1").Error
Update("login_secret", "").Error
} }
func (s *SettingService) getSetting(key string) (*model.Setting, error) { func (s *SettingService) getSetting(key string) (*model.Setting, error) {
@ -315,6 +318,22 @@ func (s *SettingService) GetTgLang() (string, error) {
return s.getString("tgLang") return s.getString("tgLang")
} }
func (s *SettingService) GetTwoFactorEnable() (bool, error) {
return s.getBool("twoFactorEnable")
}
func (s *SettingService) SetTwoFactorEnable(value bool) error {
return s.setBool("twoFactorEnable", value)
}
func (s *SettingService) GetTwoFactorToken() (string, error) {
return s.getString("twoFactorToken")
}
func (s *SettingService) SetTwoFactorToken(value string) error {
return s.setString("twoFactorToken", value)
}
func (s *SettingService) GetPort() (int, error) { func (s *SettingService) GetPort() (int, error) {
return s.getInt("webPort") return s.getInt("webPort")
} }
@ -355,14 +374,6 @@ func (s *SettingService) GetRemarkModel() (string, error) {
return s.getString("remarkModel") return s.getString("remarkModel")
} }
func (s *SettingService) GetSecretStatus() (bool, error) {
return s.getBool("secretEnable")
}
func (s *SettingService) SetSecretStatus(value bool) error {
return s.setBool("secretEnable", value)
}
func (s *SettingService) GetSecret() ([]byte, error) { func (s *SettingService) GetSecret() ([]byte, error) {
secret, err := s.getString("secret") secret, err := s.getString("secret")
if secret == defaultValueMap["secret"] { if secret == defaultValueMap["secret"] {
@ -416,6 +427,10 @@ func (s *SettingService) GetSubEnable() (bool, error) {
return s.getBool("subEnable") return s.getBool("subEnable")
} }
func (s *SettingService) GetSubTitle() (string, error) {
return s.getString("subTitle")
}
func (s *SettingService) GetSubListen() (string, error) { func (s *SettingService) GetSubListen() (string, error) {
return s.getString("subListen") return s.getString("subListen")
} }
@ -496,6 +511,22 @@ func (s *SettingService) SetWarp(data string) error {
return s.setString("warp", data) return s.setString("warp", data)
} }
func (s *SettingService) GetExternalTrafficInformEnable() (bool, error) {
return s.getBool("externalTrafficInformEnable")
}
func (s *SettingService) SetExternalTrafficInformEnable(value bool) error {
return s.setBool("externalTrafficInformEnable", value)
}
func (s *SettingService) GetExternalTrafficInformURI() (string, error) {
return s.getString("externalTrafficInformURI")
}
func (s *SettingService) SetExternalTrafficInformURI(InformURI string) error {
return s.setString("externalTrafficInformURI", InformURI)
}
func (s *SettingService) GetIpLimitEnable() (bool, error) { func (s *SettingService) GetIpLimitEnable() (bool, error) {
accessLogPath, err := xray.GetAccessLogPath() accessLogPath, err := xray.GetAccessLogPath()
if err != nil { if err != nil {
@ -525,8 +556,8 @@ func (s *SettingService) UpdateAllSetting(allSetting *entity.AllSetting) error {
return common.Combine(errs...) return common.Combine(errs...)
} }
func (s *SettingService) GetDefaultXrayConfig() (interface{}, error) { func (s *SettingService) GetDefaultXrayConfig() (any, error) {
var jsonData interface{} var jsonData any
err := json.Unmarshal([]byte(xrayTemplateConfig), &jsonData) err := json.Unmarshal([]byte(xrayTemplateConfig), &jsonData)
if err != nil { if err != nil {
return nil, err return nil, err
@ -534,24 +565,25 @@ func (s *SettingService) GetDefaultXrayConfig() (interface{}, error) {
return jsonData, nil return jsonData, nil
} }
func (s *SettingService) GetDefaultSettings(host string) (interface{}, error) { func (s *SettingService) GetDefaultSettings(host string) (any, error) {
type settingFunc func() (interface{}, error) type settingFunc func() (any, error)
settings := map[string]settingFunc{ settings := map[string]settingFunc{
"expireDiff": func() (interface{}, error) { return s.GetExpireDiff() }, "expireDiff": func() (any, error) { return s.GetExpireDiff() },
"trafficDiff": func() (interface{}, error) { return s.GetTrafficDiff() }, "trafficDiff": func() (any, error) { return s.GetTrafficDiff() },
"pageSize": func() (interface{}, error) { return s.GetPageSize() }, "pageSize": func() (any, error) { return s.GetPageSize() },
"defaultCert": func() (interface{}, error) { return s.GetCertFile() }, "defaultCert": func() (any, error) { return s.GetCertFile() },
"defaultKey": func() (interface{}, error) { return s.GetKeyFile() }, "defaultKey": func() (any, error) { return s.GetKeyFile() },
"tgBotEnable": func() (interface{}, error) { return s.GetTgbotEnabled() }, "tgBotEnable": func() (any, error) { return s.GetTgbotEnabled() },
"subEnable": func() (interface{}, error) { return s.GetSubEnable() }, "subEnable": func() (any, error) { return s.GetSubEnable() },
"subURI": func() (interface{}, error) { return s.GetSubURI() }, "subTitle": func() (any, error) { return s.GetSubTitle() },
"subJsonURI": func() (interface{}, error) { return s.GetSubJsonURI() }, "subURI": func() (any, error) { return s.GetSubURI() },
"remarkModel": func() (interface{}, error) { return s.GetRemarkModel() }, "subJsonURI": func() (any, error) { return s.GetSubJsonURI() },
"datepicker": func() (interface{}, error) { return s.GetDatepicker() }, "remarkModel": func() (any, error) { return s.GetRemarkModel() },
"ipLimitEnable": func() (interface{}, error) { return s.GetIpLimitEnable() }, "datepicker": func() (any, error) { return s.GetDatepicker() },
"ipLimitEnable": func() (any, error) { return s.GetIpLimitEnable() },
} }
result := make(map[string]interface{}) result := make(map[string]any)
for key, fn := range settings { for key, fn := range settings {
value, err := fn() value, err := fn()
@ -563,6 +595,7 @@ func (s *SettingService) GetDefaultSettings(host string) (interface{}, error) {
if result["subEnable"].(bool) && (result["subURI"].(string) == "" || result["subJsonURI"].(string) == "") { if result["subEnable"].(bool) && (result["subURI"].(string) == "" || result["subJsonURI"].(string) == "") {
subURI := "" subURI := ""
subTitle, _ := s.GetSubTitle()
subPort, _ := s.GetSubPort() subPort, _ := s.GetSubPort()
subPath, _ := s.GetSubPath() subPath, _ := s.GetSubPath()
subJsonPath, _ := s.GetSubJsonPath() subJsonPath, _ := s.GetSubJsonPath()
@ -589,6 +622,9 @@ func (s *SettingService) GetDefaultSettings(host string) (interface{}, error) {
if result["subURI"].(string) == "" { if result["subURI"].(string) == "" {
result["subURI"] = subURI + subPath result["subURI"] = subURI + subPath
} }
if result["subTitle"].(string) == "" {
result["subTitle"] = subTitle
}
if result["subJsonURI"].(string) == "" { if result["subJsonURI"].(string) == "" {
result["subJsonURI"] = subURI + subJsonPath result["subJsonURI"] = subURI + subJsonPath
} }

File diff suppressed because it is too large Load Diff