diff --git a/Dockerfile b/Dockerfile index 2722180..fe25484 100644 --- a/Dockerfile +++ b/Dockerfile @@ -111,6 +111,7 @@ ENV MESHSTREAM_MQTT_USERNAME=meshdev ENV MESHSTREAM_MQTT_PASSWORD=large4cats ENV MESHSTREAM_MQTT_TOPIC_PREFIX=msh/US/bayarea ENV MESHSTREAM_MQTT_CLIENT_ID=meshstream +ENV MESHSTREAM_CHANNEL_KEYS="" # Note: Web app configuration is set at build time # and baked into the static files diff --git a/docker-compose.yml b/docker-compose.yml index 397e768..01c78c0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -35,6 +35,9 @@ services: - MESHSTREAM_LOG_LEVEL=${MESHSTREAM_LOG_LEVEL:-info} - MESHSTREAM_VERBOSE_LOGGING=${MESHSTREAM_VERBOSE_LOGGING:-false} - MESHSTREAM_CACHE_SIZE=${MESHSTREAM_CACHE_SIZE:-1000} + + # Channel keys for decryption + - MESHSTREAM_CHANNEL_KEYS=${MESHSTREAM_CHANNEL_KEYS:-} restart: unless-stopped healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/api/status"] diff --git a/main.go b/main.go index 62637ed..bd01bf6 100644 --- a/main.go +++ b/main.go @@ -75,7 +75,7 @@ func parseConfig() *Config { flag.StringVar(&config.StaticDir, "static-dir", getEnv("STATIC_DIR", "./server/static"), "Directory containing static web files") // Channel key configuration (comma separated list of name:key pairs) - channelKeysDefault := getEnv("CHANNEL_KEYS", "LongFast:"+decoder.DefaultPrivateKey+",ERSN:VIuMtC5uDDJtC/ojdH314HLkDIHanX4LdbK5yViV9jA=") + channelKeysDefault := getEnv("CHANNEL_KEYS", "LongFast:"+decoder.DefaultPrivateKey) channelKeysFlag := flag.String("channel-keys", channelKeysDefault, "Comma-separated list of channel:key pairs for encrypted channels") // Statistics configuration @@ -214,6 +214,7 @@ func main() { MQTTServer: config.MQTTBroker, MQTTTopicPath: config.MQTTTopicPrefix + "/#", StaticDir: config.StaticDir, + ChannelKeys: config.ChannelKeys, }) // Start the server in a goroutine diff --git a/server/server.go b/server/server.go index f28c422..2cd4902 100644 --- a/server/server.go +++ b/server/server.go @@ -6,6 +6,7 @@ import ( "fmt" "net/http" "strconv" + "strings" "sync/atomic" "time" @@ -25,6 +26,7 @@ type Config struct { MQTTServer string // MQTT server hostname MQTTTopicPath string // MQTT topic path being subscribed to StaticDir string // Directory containing static web files + ChannelKeys []string // Channel keys for decryption } // Create connection info JSON to send to the client @@ -111,12 +113,22 @@ func (s *Server) Stop() error { func (s *Server) handleStatus(w http.ResponseWriter, r *http.Request) { logger := s.logger.Named("api.status") + // Extract channel names without keys for security + var channelNames []string + for _, channelKeyPair := range s.config.ChannelKeys { + parts := strings.SplitN(channelKeyPair, ":", 2) + if len(parts) == 2 { + channelNames = append(channelNames, parts[0]) + } + } + status := map[string]interface{}{ "status": "ok", "message": "Meshtastic Stream API is running", "activeConnections": s.activeConnections.Load(), "mqttServer": s.config.MQTTServer, "mqttTopic": s.config.MQTTTopicPath, + "channels": channelNames, } logger.Debug("Status endpoint called")