From 987244019c9b5410682709a5f51b68ae0cd10ac5 Mon Sep 17 00:00:00 2001 From: Hein Date: Tue, 6 Jan 2026 14:05:36 +0200 Subject: [PATCH] =?UTF-8?q?feat(cors):=20=E2=9C=A8=20enhance=20CORS=20conf?= =?UTF-8?q?iguration=20with=20dynamic=20origins?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update CORSConfig to allow dynamic origins based on server instances. * Add ExternalURLs field to ServerInstanceConfig for additional CORS support. * Implement GetIPs function to retrieve non-local IP addresses for CORS. --- pkg/common/cors.go | 24 +++++++++++++++++++++++- pkg/config/config.go | 3 +++ pkg/config/manager.go | 13 ++++++++++++- pkg/config/server.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/pkg/common/cors.go b/pkg/common/cors.go index 8c39fb1..529a806 100644 --- a/pkg/common/cors.go +++ b/pkg/common/cors.go @@ -3,6 +3,8 @@ package common import ( "fmt" "strings" + + "github.com/bitechdev/ResolveSpec/pkg/config" ) // CORSConfig holds CORS configuration @@ -15,8 +17,28 @@ type CORSConfig struct { // DefaultCORSConfig returns a default CORS configuration suitable for HeadSpec func DefaultCORSConfig() CORSConfig { + configManager := config.GetConfigManager() + cfg, _ := configManager.GetConfig() + hosts := make([]string, 0) + //hosts = append(hosts, "*") + + _, _, ipsList := config.GetIPs() + + for _, server := range cfg.Servers.Instances { + hosts = append(hosts, fmt.Sprintf("http://%s:%d", server.Host, server.Port)) + hosts = append(hosts, fmt.Sprintf("https://%s:%d", server.Host, server.Port)) + hosts = append(hosts, fmt.Sprintf("http://%s:%d", "localhost", server.Port)) + for _, extURL := range server.ExternalURLs { + hosts = append(hosts, extURL) + } + for _, ip := range ipsList { + hosts = append(hosts, fmt.Sprintf("http://%s:%d", ip.String(), server.Port)) + hosts = append(hosts, fmt.Sprintf("https://%s:%d", ip.String(), server.Port)) + } + } + return CORSConfig{ - AllowedOrigins: []string{"*"}, + AllowedOrigins: hosts, AllowedMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"}, AllowedHeaders: GetHeadSpecHeaders(), MaxAge: 86400, // 24 hours diff --git a/pkg/config/config.go b/pkg/config/config.go index faa8387..b6265bf 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -73,6 +73,9 @@ type ServerInstanceConfig struct { // Tags for organization and filtering Tags map[string]string `mapstructure:"tags"` + + // ExternalURLs are additional URLs that this server instance is accessible from (for CORS) for proxy setups + ExternalURLs []string `mapstructure:"external_urls"` } // TracingConfig holds OpenTelemetry tracing configuration diff --git a/pkg/config/manager.go b/pkg/config/manager.go index ec6351c..391c6b0 100644 --- a/pkg/config/manager.go +++ b/pkg/config/manager.go @@ -12,6 +12,16 @@ type Manager struct { v *viper.Viper } +var configInstance *Manager + +// GetConfigManager returns a singleton configuration manager instance +func GetConfigManager() *Manager { + if configInstance == nil { + configInstance = NewManager() + } + return configInstance +} + // NewManager creates a new configuration manager with defaults func NewManager() *Manager { v := viper.New() @@ -32,7 +42,8 @@ func NewManager() *Manager { // Set default values setDefaults(v) - return &Manager{v: v} + configInstance = &Manager{v: v} + return configInstance } // NewManagerWithOptions creates a new configuration manager with custom options diff --git a/pkg/config/server.go b/pkg/config/server.go index f28008c..a532f5e 100644 --- a/pkg/config/server.go +++ b/pkg/config/server.go @@ -2,6 +2,9 @@ package config import ( "fmt" + "net" + "os" + "strings" ) // ApplyGlobalDefaults applies global server defaults to this instance @@ -105,3 +108,42 @@ func (sc *ServersConfig) GetDefault() (*ServerInstanceConfig, error) { return &instance, nil } + +// GetIPs - GetIP for pc +func GetIPs() (string, string, []net.IP) { + defer func() { + if err := recover(); err != nil { + fmt.Println("Recovered in GetIPs", err) + } + }() + hostname, _ := os.Hostname() + ipaddrlist := make([]net.IP, 0) + iplist := "" + addrs, err := net.LookupIP(hostname) + if err != nil { + return hostname, iplist, ipaddrlist + } + + for _, a := range addrs { + //cfg.LogInfo("\nFound IP Host Address: %s", a) + if strings.Contains(a.String(), "127.0.0.1") { + continue + } + iplist = fmt.Sprintf("%s,%s", iplist, a) + ipaddrlist = append(ipaddrlist, a) + } + if iplist == "" { + iff, _ := net.InterfaceAddrs() + for _, a := range iff { + //cfg.LogInfo("\nFound IP Address: %s", a) + if strings.Contains(a.String(), "127.0.0.1") { + continue + } + iplist = fmt.Sprintf("%s,%s", iplist, a) + + } + + } + iplist = strings.TrimLeft(iplist, ",") + return hostname, iplist, ipaddrlist +}