Files
beacon-server/internal/config/channels.go
T

67 lines
1.9 KiB
Go

// Copyright 2026 Beacon Contributors
// SPDX-License-Identifier: AGPL-3.0-or-later
package config
import (
"encoding/hex"
"fmt"
"strings"
"github.com/MeshCore-Beacon/beacon-server/internal/keystore"
"gopkg.in/yaml.v3"
)
// HashtagConfig is a hashtag channel; a plain string in YAML is a Beacon-wide one.
type HashtagConfig struct {
Name string `yaml:"name"`
Region string `yaml:"region"` // optional region slug
}
func (h *HashtagConfig) UnmarshalYAML(node *yaml.Node) error {
if node.Kind == yaml.ScalarNode {
return node.Decode(&h.Name)
}
type plain HashtagConfig
return node.Decode((*plain)(h))
}
// ChannelScope places a configured channel under a region, or Beacon-wide when Region is empty.
type ChannelScope struct {
Fingerprint []byte
Region string
}
func (c *Config) validateChannelKeys() error {
for i, h := range c.ChannelKeys.Hashtags {
if strings.TrimSpace(h.Name) == "" {
return fmt.Errorf("channel_keys.hashtags[%d] needs a name", i)
}
if h.Region != "" && c.region(h.Region) == nil {
return fmt.Errorf("channel #%s region %q is not a configured region", h.Name, h.Region)
}
}
for hash, k := range c.ChannelKeys.Keys {
if k.Region != "" && c.region(k.Region) == nil {
return fmt.Errorf("channel key %s region %q is not a configured region", hash, k.Region)
}
}
return nil
}
// ChannelScopes lists every configured channel's region placement. Keys that
// aren't valid hex are skipped; startup already warns about them.
func (c *Config) ChannelScopes() []ChannelScope {
var scopes []ChannelScope
for _, h := range c.ChannelKeys.Hashtags {
_, _, fingerprint := keystore.DeriveHashtagKey(h.Name)
scopes = append(scopes, ChannelScope{Fingerprint: fingerprint, Region: h.Region})
}
for _, k := range c.ChannelKeys.Keys {
if key, err := hex.DecodeString(k.Key); err == nil {
scopes = append(scopes, ChannelScope{Fingerprint: keystore.Fingerprint(key), Region: k.Region})
}
}
return scopes
}