fix callback URL to use configurable public base
Separate callback URL generation from LISTEN_ADDR by introducing CALLBACK_BASE_URL with a localhost default for local development. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,9 @@ type Config struct {
|
||||
|
||||
// Server
|
||||
ListenAddr string
|
||||
|
||||
// Public callback base URL for OpenClaw callbacks
|
||||
CallbackBaseURL string
|
||||
}
|
||||
|
||||
// Load reads .env (if present) and populates Config from environment variables.
|
||||
@@ -59,6 +62,7 @@ func Load() (*Config, error) {
|
||||
SystemEmail: os.Getenv("SYSTEM_EMAIL"),
|
||||
IMAPProxyURL: os.Getenv("IMAP_PROXY_URL"),
|
||||
ListenAddr: os.Getenv("LISTEN_ADDR"),
|
||||
CallbackBaseURL: os.Getenv("CALLBACK_BASE_URL"),
|
||||
}
|
||||
|
||||
if raw := os.Getenv("WHITELIST_EMAILS"); raw != "" {
|
||||
@@ -72,6 +76,9 @@ func Load() (*Config, error) {
|
||||
if cfg.ListenAddr == "" {
|
||||
cfg.ListenAddr = ":8080"
|
||||
}
|
||||
if cfg.CallbackBaseURL == "" {
|
||||
cfg.CallbackBaseURL = "http://localhost"
|
||||
}
|
||||
|
||||
if err := cfg.validate(); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package config
|
||||
|
||||
import "testing"
|
||||
|
||||
func setRequiredEnv(t *testing.T) {
|
||||
t.Helper()
|
||||
t.Setenv("IMAP_HOST", "imap.example.com")
|
||||
t.Setenv("IMAP_PORT", "993")
|
||||
t.Setenv("IMAP_USER", "u")
|
||||
t.Setenv("IMAP_PASS", "p")
|
||||
t.Setenv("SMTP_HOST", "smtp.example.com")
|
||||
t.Setenv("SMTP_PORT", "587")
|
||||
t.Setenv("SMTP_USER", "u")
|
||||
t.Setenv("SMTP_PASS", "p")
|
||||
t.Setenv("OPENCLAW_URL", "http://openclaw.local")
|
||||
t.Setenv("BRIDGE_CALLBACK_TOKEN", "token")
|
||||
t.Setenv("SYSTEM_EMAIL", "system@example.com")
|
||||
t.Setenv("LISTEN_ADDR", ":8080")
|
||||
t.Setenv("WHITELIST_EMAILS", "")
|
||||
t.Setenv("IMAP_PROXY_URL", "")
|
||||
t.Setenv("OPENCLAW_API_KEY", "")
|
||||
}
|
||||
|
||||
func TestLoad_DefaultCallbackBaseURL_WhenUnset(t *testing.T) {
|
||||
setRequiredEnv(t)
|
||||
t.Setenv("CALLBACK_BASE_URL", "")
|
||||
|
||||
cfg, err := Load()
|
||||
if err != nil {
|
||||
t.Fatalf("load config: %v", err)
|
||||
}
|
||||
|
||||
if cfg.CallbackBaseURL != "http://localhost" {
|
||||
t.Fatalf("expected default callback base URL http://localhost, got %q", cfg.CallbackBaseURL)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoad_UsesCallbackBaseURL_WhenSet(t *testing.T) {
|
||||
setRequiredEnv(t)
|
||||
t.Setenv("CALLBACK_BASE_URL", "https://bridge.example.com")
|
||||
|
||||
cfg, err := Load()
|
||||
if err != nil {
|
||||
t.Fatalf("load config: %v", err)
|
||||
}
|
||||
|
||||
if cfg.CallbackBaseURL != "https://bridge.example.com" {
|
||||
t.Fatalf("expected callback base URL from env, got %q", cfg.CallbackBaseURL)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user