Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/rand"
"encoding/hex"
"errors"
"flag"
"net/http"
"os"
"os/signal"
Expand All @@ -18,6 +19,9 @@ import (
)

func main() {
// Parse command line flags
portFlag := flag.Int("port", 0, "Force specific port (locked, cannot be changed via API)")
flag.Parse()
dataDir := resolveDataDir()
if err := os.MkdirAll(dataDir, 0755); err != nil {
logger.Error("Failed to create data dir %s: %v", dataDir, err)
Expand All @@ -42,6 +46,13 @@ func main() {
os.Exit(1)
}

// Handle -port CLI flag (overrides config and locks port)
if *portFlag > 0 {
cfg.Port = *portFlag
cfg.LockPort()
logger.Info("Port locked to %d via CLI flag", *portFlag)
}

if cfg.BasicAuthEnabled && cfg.BasicAuthPassword == "" {
randomPassword := generateRandomPassword(16)
cfg.BasicAuthPassword = randomPassword
Expand Down Expand Up @@ -192,4 +203,4 @@ func generateRandomPassword(length int) string {
return string(fallback)
}
return hex.EncodeToString(bytes)[:length]
}
}
8 changes: 7 additions & 1 deletion cmd/server/webui/api/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,15 @@ func (h *Handler) handleConfigPort(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
WriteSuccess(w, map[string]interface{}{
"port": h.config.GetPort(),
"port": h.config.GetPort(),
"portLocked": h.config.IsPortLocked(),
})
case http.MethodPut:
if h.config.IsPortLocked() {
WriteError(w, http.StatusForbidden, "Port is locked by CLI flag and cannot be changed")
return
}

var req struct {
Port int `json:"port"`
}
Expand Down
19 changes: 19 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ type ProxyConfig struct {
// Config represents the application configuration
type Config struct {
Port int `json:"port"`
PortLocked bool `json:"-"` // CLI forced port, cannot be changed via API
BasicAuthEnabled bool `json:"basicAuthEnabled"`
BasicAuthUsername string `json:"basicAuthUsername"`
BasicAuthPassword string `json:"basicAuthPassword"`
Expand Down Expand Up @@ -318,12 +319,30 @@ func (c *Config) UpdateEndpoints(endpoints []Endpoint) {
}

// UpdatePort updates the port (thread-safe)
// If PortLocked is true, the port cannot be changed
func (c *Config) UpdatePort(port int) {
c.mu.Lock()
defer c.mu.Unlock()
if c.PortLocked {
return
}
c.Port = port
}

// LockPort locks the port so it cannot be changed via API
func (c *Config) LockPort() {
c.mu.Lock()
defer c.mu.Unlock()
c.PortLocked = true
}

// IsPortLocked returns true if the port is locked
func (c *Config) IsPortLocked() bool {
c.mu.RLock()
defer c.mu.RUnlock()
return c.PortLocked
}

// UpdateLogLevel updates the log level (thread-safe)
func (c *Config) UpdateLogLevel(level int) {
c.mu.Lock()
Expand Down
Loading