mirror of
https://github.com/MeshCore-Beacon/beacon-server.git
synced 2026-10-17 22:20:12 +00:00
67 lines
1.9 KiB
Go
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
|
|
}
|