diff --git a/internal/config/settings.go b/internal/config/settings.go index 65601c4..809c11f 100644 --- a/internal/config/settings.go +++ b/internal/config/settings.go @@ -1321,6 +1321,15 @@ func GetPortFromEnv() (int, bool) { return 0, false } +// GetCallbackURLFromEnv returns the CALLBACK_URL environment variable value and whether it's set. +func GetCallbackURLFromEnv() (string, bool) { + v := strings.TrimSpace(os.Getenv("CALLBACK_URL")) + if v == "" { + return "", false + } + return strings.TrimRight(v, "/"), true +} + // GetBindAddressFromEnv returns the BIND_ADDRESS environment variable value if set, and whether it's set // If not set, returns "0.0.0.0" as the default bind address // Validates that the address is a valid IP address format diff --git a/pkg/web/handlers.go b/pkg/web/handlers.go index 9f4dcf6..93bd021 100644 --- a/pkg/web/handlers.go +++ b/pkg/web/handlers.go @@ -2078,6 +2078,14 @@ func GetSettingsHandler(c *gin.Context) { response["port"] = envPort } + // Check if CALLBACK_URL environment variable is set + envCallbackURL, envCallbackURLSet := config.GetCallbackURLFromEnv() + response["callbackUrlEnvSet"] = envCallbackURLSet + response["callbackUrlFromEnv"] = envCallbackURL + if envCallbackURLSet { + response["callbackUrl"] = envCallbackURL + } + c.JSON(http.StatusOK, response) } @@ -2103,6 +2111,12 @@ func UpdateSettingsHandler(c *gin.Context) { req.Port = envPort } + // Check if CALLBACK_URL environment variable is set - if so, ignore changes from request + envCallbackURL, envCallbackURLSet := config.GetCallbackURLFromEnv() + if envCallbackURLSet { + req.CallbackURL = envCallbackURL + } + oldSettings := config.GetSettings() newSettings, err := config.UpdateSettings(req) if err != nil { diff --git a/pkg/web/static/js/settings.js b/pkg/web/static/js/settings.js index 41da752..4ef3bad 100644 --- a/pkg/web/static/js/settings.js +++ b/pkg/web/static/js/settings.js @@ -85,6 +85,26 @@ function loadSettings() { // Set callback URL and add auto-update listener for port changes const callbackURLInput = document.getElementById('callbackURL'); callbackURLInput.value = data.callbackUrl || ''; + const callbackUrlEnvHint = document.getElementById('callbackUrlEnvHint'); + const callbackUrlEnvValue = document.getElementById('callbackUrlEnvValue'); + const callbackUrlDefaultHint = document.getElementById('callbackUrlDefaultHint'); + + if (data.callbackUrlEnvSet) { + // CALLBACK_URL env is set - make field readonly and show hint + callbackURLInput.value = data.callbackUrlFromEnv || data.callbackUrl || ''; + callbackURLInput.readOnly = true; + callbackURLInput.classList.add('bg-gray-100', 'cursor-not-allowed'); + callbackUrlEnvValue.textContent = data.callbackUrlFromEnv || data.callbackUrl || ''; + callbackUrlEnvHint.style.display = 'block'; + callbackUrlDefaultHint.style.display = 'none'; + } else { + // CALLBACK_URL env not set - allow editing + callbackURLInput.readOnly = false; + callbackURLInput.classList.remove('bg-gray-100', 'cursor-not-allowed'); + callbackUrlEnvHint.style.display = 'none'; + callbackUrlDefaultHint.style.display = 'block'; + } + const callbackSecretInput = document.getElementById('callbackSecret'); const toggleLink = document.getElementById('toggleCallbackSecretLink'); if (callbackSecretInput) { @@ -101,6 +121,7 @@ function loadSettings() { // Auto-update callback URL when port changes (if using default localhost pattern) function updateCallbackURLIfDefault() { + if (data.callbackUrlEnvSet) return; // Skip auto-update when env is set const currentPort = parseInt(uiPortInput.value, 10) || 8080; const currentCallbackURL = callbackURLInput.value.trim(); // Check if callback URL matches default localhost pattern diff --git a/pkg/web/templates/index.html b/pkg/web/templates/index.html index 8d3e7f7..95f6c50 100644 --- a/pkg/web/templates/index.html +++ b/pkg/web/templates/index.html @@ -313,7 +313,11 @@ -

This URL is used by all Fail2Ban instances to send ban alerts back to Fail2Ban UI. For local deployments, use the same port as Fail2Ban UI (e.g., http://127.0.0.1:8080). For reverse proxy setups, use your TLS-encrypted endpoint (e.g., https://fail2ban.example.com).

+ +

This URL is used by all Fail2Ban instances to send ban alerts back to Fail2Ban UI. For local deployments, use the same port as Fail2Ban UI (e.g., http://127.0.0.1:8080). For reverse proxy setups, use your TLS-encrypted endpoint (e.g., https://fail2ban.example.com).