mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-10-13 11:39:13 +00:00
commit
806ecbd7c5
5 changed files with 65 additions and 15 deletions
3
.github/workflows/docker.yml
vendored
3
.github/workflows/docker.yml
vendored
|
@ -1,4 +1,7 @@
|
|||
name: Release 3X-UI for Docker
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
|
|
|
@ -23,11 +23,11 @@ type LogLevel string
|
|||
|
||||
// Logging level constants
|
||||
const (
|
||||
Debug LogLevel = "debug"
|
||||
Info LogLevel = "info"
|
||||
Notice LogLevel = "notice"
|
||||
Warn LogLevel = "warn"
|
||||
Error LogLevel = "error"
|
||||
Debug LogLevel = "debug"
|
||||
Info LogLevel = "info"
|
||||
Notice LogLevel = "notice"
|
||||
Warning LogLevel = "warning"
|
||||
Error LogLevel = "error"
|
||||
)
|
||||
|
||||
// GetVersion returns the version string of the 3x-ui application.
|
||||
|
|
2
main.go
2
main.go
|
@ -35,7 +35,7 @@ func runWebServer() {
|
|||
logger.InitLogger(logging.INFO)
|
||||
case config.Notice:
|
||||
logger.InitLogger(logging.NOTICE)
|
||||
case config.Warn:
|
||||
case config.Warning:
|
||||
logger.InitLogger(logging.WARNING)
|
||||
case config.Error:
|
||||
logger.InitLogger(logging.ERROR)
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
package random
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -40,12 +41,21 @@ func init() {
|
|||
func Seq(n int) string {
|
||||
runes := make([]rune, n)
|
||||
for i := 0; i < n; i++ {
|
||||
runes[i] = allSeq[rand.Intn(len(allSeq))]
|
||||
idx, err := rand.Int(rand.Reader, big.NewInt(int64(len(allSeq))))
|
||||
if err != nil {
|
||||
panic("crypto/rand failed: " + err.Error())
|
||||
}
|
||||
runes[i] = allSeq[idx.Int64()]
|
||||
}
|
||||
return string(runes)
|
||||
}
|
||||
|
||||
// Num generates a random integer between 0 and n-1.
|
||||
func Num(n int) int {
|
||||
return rand.Intn(n)
|
||||
bn := big.NewInt(int64(n))
|
||||
r, err := rand.Int(rand.Reader, bn)
|
||||
if err != nil {
|
||||
panic("crypto/rand failed: " + err.Error())
|
||||
}
|
||||
return int(r.Int64())
|
||||
}
|
||||
|
|
|
@ -697,14 +697,39 @@ func (s *ServerService) GetLogs(count string, level string, syslog string) []str
|
|||
var lines []string
|
||||
|
||||
if syslog == "true" {
|
||||
cmdArgs := []string{"journalctl", "-u", "x-ui", "--no-pager", "-n", count, "-p", level}
|
||||
// Run the command
|
||||
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
|
||||
// Check if running on Windows - journalctl is not available
|
||||
if runtime.GOOS == "windows" {
|
||||
return []string{"Syslog is not supported on Windows. Please use application logs instead by unchecking the 'Syslog' option."}
|
||||
}
|
||||
|
||||
// Validate and sanitize count parameter
|
||||
countInt, err := strconv.Atoi(count)
|
||||
if err != nil || countInt < 1 || countInt > 10000 {
|
||||
return []string{"Invalid count parameter - must be a number between 1 and 10000"}
|
||||
}
|
||||
|
||||
// Validate level parameter - only allow valid syslog levels
|
||||
validLevels := map[string]bool{
|
||||
"0": true, "emerg": true,
|
||||
"1": true, "alert": true,
|
||||
"2": true, "crit": true,
|
||||
"3": true, "err": true,
|
||||
"4": true, "warning": true,
|
||||
"5": true, "notice": true,
|
||||
"6": true, "info": true,
|
||||
"7": true, "debug": true,
|
||||
}
|
||||
if !validLevels[level] {
|
||||
return []string{"Invalid level parameter - must be a valid syslog level"}
|
||||
}
|
||||
|
||||
// Use hardcoded command with validated parameters
|
||||
cmd := exec.Command("journalctl", "-u", "x-ui", "--no-pager", "-n", strconv.Itoa(countInt), "-p", level)
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
err := cmd.Run()
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return []string{"Failed to run journalctl command!"}
|
||||
return []string{"Failed to run journalctl command! Make sure systemd is available and x-ui service is registered."}
|
||||
}
|
||||
lines = strings.Split(out.String(), "\n")
|
||||
} else {
|
||||
|
@ -983,7 +1008,19 @@ func (s *ServerService) UpdateGeofile(fileName string) error {
|
|||
{"https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat", "geoip_RU.dat"},
|
||||
{"https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat", "geosite_RU.dat"},
|
||||
}
|
||||
|
||||
// Strict allowlist check to avoid writing uncontrolled files
|
||||
if fileName != "" {
|
||||
isAllowed := false
|
||||
for _, file := range files {
|
||||
if fileName == file.FileName {
|
||||
isAllowed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isAllowed {
|
||||
return common.NewErrorf("Invalid geofile name: %s", fileName)
|
||||
}
|
||||
}
|
||||
downloadFile := func(url, destPath string) error {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue