Browse Source

Refactor code and fix linter warnings (#3627)

* refactor: use any instead of empty interface

* refactor: code cleanup
Ilya Kryuchkov 3 days ago
parent
commit
6041d10e3d

+ 3 - 3
main.go

@@ -80,8 +80,8 @@ func runWebServer() {
 
 			// --- FIX FOR TELEGRAM BOT CONFLICT (409): Stop bot before restart ---
 			service.StopBot()
-			// --			
-			
+			// --
+
 			err := server.Stop()
 			if err != nil {
 				logger.Debug("Error stopping web server:", err)
@@ -113,7 +113,7 @@ func runWebServer() {
 			// --- FIX FOR TELEGRAM BOT CONFLICT (409) on full shutdown ---
 			service.StopBot()
 			// ------------------------------------------------------------
-			
+
 			server.Stop()
 			subServer.Stop()
 			log.Println("Shutting down servers.")

+ 3 - 3
sub/subJsonService.go

@@ -4,6 +4,7 @@ import (
 	_ "embed"
 	"encoding/json"
 	"fmt"
+	"maps"
 	"strings"
 
 	"github.com/mhsanaei/3x-ui/v2/database/model"
@@ -197,9 +198,8 @@ func (s *SubJsonService) getConfig(inbound *model.Inbound, client model.Client,
 
 		newOutbounds = append(newOutbounds, s.defaultOutbounds...)
 		newConfigJson := make(map[string]any)
-		for key, value := range s.configJson {
-			newConfigJson[key] = value
-		}
+		maps.Copy(newConfigJson, s.configJson)
+
 		newConfigJson["outbounds"] = newOutbounds
 		newConfigJson["remarks"] = s.SubService.genRemark(inbound, client.Email, extPrxy["remark"].(string))
 

+ 4 - 7
sub/subService.go

@@ -484,8 +484,8 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
 	externalProxies, _ := stream["externalProxy"].([]any)
 
 	if len(externalProxies) > 0 {
-		links := ""
-		for index, externalProxy := range externalProxies {
+		links := make([]string, 0, len(externalProxies))
+		for _, externalProxy := range externalProxies {
 			ep, _ := externalProxy.(map[string]any)
 			newSecurity, _ := ep["forceTls"].(string)
 			dest, _ := ep["dest"].(string)
@@ -511,12 +511,9 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
 
 			url.Fragment = s.genRemark(inbound, email, ep["remark"].(string))
 
-			if index > 0 {
-				links += "\n"
-			}
-			links += url.String()
+			links = append(links, url.String())
 		}
-		return links
+		return strings.Join(links, "\n")
 	}
 
 	link := fmt.Sprintf("vless://%s@%s:%d", uuid, address, port)

+ 1 - 2
util/crypto/crypto.go

@@ -13,6 +13,5 @@ func HashPasswordAsBcrypt(password string) (string, error) {
 
 // CheckPasswordHash verifies if the given password matches the bcrypt hash.
 func CheckPasswordHash(hash, password string) bool {
-	err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
-	return err == nil
+	return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil
 }

+ 28 - 10
util/ldap/ldap.go

@@ -24,13 +24,22 @@ type Config struct {
 // FetchVlessFlags returns map[email]enabled
 func FetchVlessFlags(cfg Config) (map[string]bool, error) {
 	addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
-	var conn *ldap.Conn
-	var err error
+
+	scheme := "ldap"
+	if cfg.UseTLS {
+		scheme = "ldaps"
+	}
+
+	ldapURL := fmt.Sprintf("%s://%s", scheme, addr)
+
+	var opts []ldap.DialOpt
 	if cfg.UseTLS {
-		conn, err = ldap.DialTLS("tcp", addr, &tls.Config{InsecureSkipVerify: false})
-	} else {
-		conn, err = ldap.Dial("tcp", addr)
+		opts = append(opts, ldap.DialWithTLSConfig(&tls.Config{
+			InsecureSkipVerify: false,
+		}))
 	}
+
+	conn, err := ldap.DialURL(ldapURL, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -91,13 +100,22 @@ func FetchVlessFlags(cfg Config) (map[string]bool, error) {
 // AuthenticateUser searches user by cfg.UserAttr and attempts to bind with provided password.
 func AuthenticateUser(cfg Config, username, password string) (bool, error) {
 	addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
-	var conn *ldap.Conn
-	var err error
+
+	scheme := "ldap"
+	if cfg.UseTLS {
+		scheme = "ldaps"
+	}
+
+	ldapURL := fmt.Sprintf("%s://%s", scheme, addr)
+
+	var opts []ldap.DialOpt
 	if cfg.UseTLS {
-		conn, err = ldap.DialTLS("tcp", addr, &tls.Config{InsecureSkipVerify: false})
-	} else {
-		conn, err = ldap.Dial("tcp", addr)
+		opts = append(opts, ldap.DialWithTLSConfig(&tls.Config{
+			InsecureSkipVerify: false,
+		}))
 	}
+
+	conn, err := ldap.DialURL(ldapURL, opts...)
 	if err != nil {
 		return false, err
 	}

+ 3 - 3
util/random/random.go

@@ -18,10 +18,10 @@ var (
 // init initializes the character sequences used for random string generation.
 // It sets up arrays for numbers, lowercase letters, uppercase letters, and combinations.
 func init() {
-	for i := 0; i < 10; i++ {
+	for i := range 10 {
 		numSeq[i] = rune('0' + i)
 	}
-	for i := 0; i < 26; i++ {
+	for i := range 26 {
 		lowerSeq[i] = rune('a' + i)
 		upperSeq[i] = rune('A' + i)
 	}
@@ -40,7 +40,7 @@ func init() {
 // Seq generates a random string of length n containing alphanumeric characters (numbers, lowercase and uppercase letters).
 func Seq(n int) string {
 	runes := make([]rune, n)
-	for i := 0; i < n; i++ {
+	for i := range n {
 		idx, err := rand.Int(rand.Reader, big.NewInt(int64(len(allSeq))))
 		if err != nil {
 			panic("crypto/rand failed: " + err.Error())

+ 2 - 2
util/reflect_util/reflect.go

@@ -7,7 +7,7 @@ import "reflect"
 func GetFields(t reflect.Type) []reflect.StructField {
 	num := t.NumField()
 	fields := make([]reflect.StructField, 0, num)
-	for i := 0; i < num; i++ {
+	for i := range num {
 		fields = append(fields, t.Field(i))
 	}
 	return fields
@@ -17,7 +17,7 @@ func GetFields(t reflect.Type) []reflect.StructField {
 func GetFieldValues(v reflect.Value) []reflect.Value {
 	num := v.NumField()
 	fields := make([]reflect.Value, 0, num)
-	for i := 0; i < num; i++ {
+	for i := range num {
 		fields = append(fields, v.Field(i))
 	}
 	return fields

+ 2 - 2
util/sys/sys_darwin.go

@@ -47,11 +47,11 @@ func CPUPercentRaw() (float64, error) {
 	var out [5]uint64
 	switch len(raw) {
 	case 5 * 8:
-		for i := 0; i < 5; i++ {
+		for i := range 5 {
 			out[i] = binary.LittleEndian.Uint64(raw[i*8 : (i+1)*8])
 		}
 	case 5 * 4:
-		for i := 0; i < 5; i++ {
+		for i := range 5 {
 			out[i] = uint64(binary.LittleEndian.Uint32(raw[i*4 : (i+1)*4]))
 		}
 	default:

+ 3 - 3
web/controller/server.go

@@ -210,10 +210,10 @@ func (a *ServerController) getXrayLogs(c *gin.Context) {
 	//getting tags for freedom and blackhole outbounds
 	config, err := a.settingService.GetDefaultXrayConfig()
 	if err == nil && config != nil {
-		if cfgMap, ok := config.(map[string]interface{}); ok {
-			if outbounds, ok := cfgMap["outbounds"].([]interface{}); ok {
+		if cfgMap, ok := config.(map[string]any); ok {
+			if outbounds, ok := cfgMap["outbounds"].([]any); ok {
 				for _, outbound := range outbounds {
-					if obMap, ok := outbound.(map[string]interface{}); ok {
+					if obMap, ok := outbound.(map[string]any); ok {
 						switch obMap["protocol"] {
 						case "freedom":
 							if tag, ok := obMap["tag"].(string); ok {

+ 1 - 1
web/global/global.go

@@ -17,7 +17,7 @@ var (
 type WebServer interface {
 	GetCron() *cron.Cron     // Get the cron scheduler
 	GetCtx() context.Context // Get the server context
-	GetWSHub() interface{}   // Get the WebSocket hub (using interface{} to avoid circular dependency)
+	GetWSHub() any           // Get the WebSocket hub (using any to avoid circular dependency)
 }
 
 // SubServer interface defines methods for accessing the subscription server instance.

+ 1 - 1
web/job/clear_logs_job.go

@@ -45,7 +45,7 @@ func (j *ClearLogsJob) Run() {
 	}
 
 	// Clear log files and copy to previous logs
-	for i := 0; i < len(logFiles); i++ {
+	for i := range len(logFiles) {
 		if i > 0 {
 			// Copy to previous logs
 			logFilePrev, err := os.OpenFile(logFilesPrev[i-1], os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)

+ 2 - 2
web/service/server.go

@@ -1205,7 +1205,7 @@ func (s *ServerService) GetNewmldsa65() (any, error) {
 	return keyPair, nil
 }
 
-func (s *ServerService) GetNewEchCert(sni string) (interface{}, error) {
+func (s *ServerService) GetNewEchCert(sni string) (any, error) {
 	// Run the command
 	cmd := exec.Command(xray.GetBinaryPath(), "tls", "ech", "--serverName", sni)
 	var out bytes.Buffer
@@ -1223,7 +1223,7 @@ func (s *ServerService) GetNewEchCert(sni string) (interface{}, error) {
 	configList := lines[1]
 	serverKeys := lines[3]
 
-	return map[string]interface{}{
+	return map[string]any{
 		"echServerKeys": serverKeys,
 		"echConfigList": configList,
 	}, nil

+ 1 - 1
web/web.go

@@ -487,6 +487,6 @@ func (s *Server) GetCron() *cron.Cron {
 }
 
 // GetWSHub returns the WebSocket hub instance.
-func (s *Server) GetWSHub() interface{} {
+func (s *Server) GetWSHub() any {
 	return s.wsHub
 }

+ 3 - 3
web/websocket/hub.go

@@ -26,7 +26,7 @@ const (
 // Message represents a WebSocket message
 type Message struct {
 	Type    MessageType `json:"type"`
-	Payload interface{} `json:"payload"`
+	Payload any         `json:"payload"`
 	Time    int64       `json:"time"`
 }
 
@@ -250,7 +250,7 @@ func (h *Hub) broadcastParallel(clients []*Client, message []byte) {
 }
 
 // Broadcast sends a message to all connected clients
-func (h *Hub) Broadcast(messageType MessageType, payload interface{}) {
+func (h *Hub) Broadcast(messageType MessageType, payload any) {
 	if h == nil {
 		return
 	}
@@ -289,7 +289,7 @@ func (h *Hub) Broadcast(messageType MessageType, payload interface{}) {
 }
 
 // BroadcastToTopic sends a message only to clients subscribed to the specific topic
-func (h *Hub) BroadcastToTopic(messageType MessageType, payload interface{}) {
+func (h *Hub) BroadcastToTopic(messageType MessageType, payload any) {
 	if h == nil {
 		return
 	}

+ 3 - 3
web/websocket/notifier.go

@@ -25,7 +25,7 @@ func GetHub() *Hub {
 }
 
 // BroadcastStatus broadcasts server status update to all connected clients
-func BroadcastStatus(status interface{}) {
+func BroadcastStatus(status any) {
 	hub := GetHub()
 	if hub != nil {
 		hub.Broadcast(MessageTypeStatus, status)
@@ -33,7 +33,7 @@ func BroadcastStatus(status interface{}) {
 }
 
 // BroadcastTraffic broadcasts traffic statistics update to all connected clients
-func BroadcastTraffic(traffic interface{}) {
+func BroadcastTraffic(traffic any) {
 	hub := GetHub()
 	if hub != nil {
 		hub.Broadcast(MessageTypeTraffic, traffic)
@@ -41,7 +41,7 @@ func BroadcastTraffic(traffic interface{}) {
 }
 
 // BroadcastInbounds broadcasts inbounds list update to all connected clients
-func BroadcastInbounds(inbounds interface{}) {
+func BroadcastInbounds(inbounds any) {
 	hub := GetHub()
 	if hub != nil {
 		hub.Broadcast(MessageTypeInbounds, inbounds)

+ 1 - 1
xray/api.go

@@ -116,7 +116,7 @@ func (x *XrayAPI) AddUser(Protocol string, inboundTag string, user map[string]an
 		}
 		// Add testseed if provided
 		if testseedVal, ok := user["testseed"]; ok {
-			if testseedArr, ok := testseedVal.([]interface{}); ok && len(testseedArr) >= 4 {
+			if testseedArr, ok := testseedVal.([]any); ok && len(testseedArr) >= 4 {
 				testseed := make([]uint32, len(testseedArr))
 				for i, v := range testseedArr {
 					if num, ok := v.(float64); ok {